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

Change subject: New Wikidata Build - 2016-09-17T10:00:02+0000
......................................................................


New Wikidata Build - 2016-09-17T10:00:02+0000

Change-Id: Ida781e06b609317b0b7ec1b80d53e16bd843ebd4
---
M composer.lock
M extensions/Wikibase/client/WikibaseClient.hooks.php
M extensions/Wikibase/client/WikibaseClient.i18n.alias.php
M extensions/Wikibase/client/WikibaseClient.php
M extensions/Wikibase/client/i18n/en.json
M extensions/Wikibase/client/i18n/qqq.json
A extensions/Wikibase/client/includes/Specials/SpecialEntityUsage.php
A 
extensions/Wikibase/client/tests/phpunit/includes/Specials/SpecialEntityUsageTest.php
M 
extensions/Wikibase/view/resources/jquery/ui/jquery.ui.EditableTemplatedWidget.js
M 
extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.aliasesview.js
M 
extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.badgeselector.js
M 
extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.descriptionview.js
M 
extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.entitytermsforlanguagelistview.js
M 
extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.entitytermsforlanguageview.js
M 
extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.entitytermsview.js
M 
extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.labelview.js
M 
extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.referenceview.js
M 
extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.sitelinkgroupview.js
M 
extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.sitelinklistview.js
M 
extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.sitelinkview.js
M 
extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.snaklistview.js
M 
extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.statementlistview.js
M 
extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.statementview.RankSelector.js
M 
extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.statementview.js
M extensions/Wikibase/view/resources/jquery/wikibase/resources.php
M extensions/Wikibase/view/resources/jquery/wikibase/snakview/resources.php
M extensions/Wikibase/view/resources/jquery/wikibase/snakview/snakview.js
M extensions/Wikibase/view/resources/wikibase/view/ViewFactory.js
M 
extensions/Wikibase/view/tests/qunit/jquery/wikibase/jquery.wikibase.referenceview.tests.js
M 
extensions/Wikibase/view/tests/qunit/jquery/wikibase/jquery.wikibase.sitelinklistview.tests.js
M 
extensions/Wikibase/view/tests/qunit/jquery/wikibase/jquery.wikibase.snaklistview.tests.js
M 
extensions/Wikibase/view/tests/qunit/jquery/wikibase/jquery.wikibase.statementlistview.tests.js
M 
extensions/Wikibase/view/tests/qunit/wikibase/view/ToolbarViewController.tests.js
M extensions/Wikibase/view/tests/qunit/wikibase/view/ViewFactory.tests.js
M vendor/composer/autoload_classmap.php
M vendor/composer/installed.json
36 files changed, 498 insertions(+), 578 deletions(-)

Approvals:
  Aude: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/composer.lock b/composer.lock
index 7d38993..1700cbe 100644
--- a/composer.lock
+++ b/composer.lock
@@ -1574,12 +1574,12 @@
             "source": {
                 "type": "git",
                 "url": 
"https://github.com/wikimedia/mediawiki-extensions-Wikibase.git";,
-                "reference": "bee7c4389ddd810ba119b0d37df97d2daf9df0f9"
+                "reference": "3dcac6c817c4ff350345f78fb902b57bf49e2a45"
             },
             "dist": {
                 "type": "zip",
-                "url": 
"https://api.github.com/repos/wikimedia/mediawiki-extensions-Wikibase/zipball/bee7c4389ddd810ba119b0d37df97d2daf9df0f9";,
-                "reference": "bee7c4389ddd810ba119b0d37df97d2daf9df0f9",
+                "url": 
"https://api.github.com/repos/wikimedia/mediawiki-extensions-Wikibase/zipball/3dcac6c817c4ff350345f78fb902b57bf49e2a45";,
+                "reference": "3dcac6c817c4ff350345f78fb902b57bf49e2a45",
                 "shasum": ""
             },
             "require": {
@@ -1653,7 +1653,7 @@
                 "wikibaserepo",
                 "wikidata"
             ],
-            "time": "2016-09-16 09:13:26"
+            "time": "2016-09-16 18:30:22"
         },
         {
             "name": "wikibase/wikimedia-badges",
diff --git a/extensions/Wikibase/client/WikibaseClient.hooks.php 
b/extensions/Wikibase/client/WikibaseClient.hooks.php
index 3e74593..476e209 100644
--- a/extensions/Wikibase/client/WikibaseClient.hooks.php
+++ b/extensions/Wikibase/client/WikibaseClient.hooks.php
@@ -27,6 +27,7 @@
 use Wikibase\Client\RecentChanges\ExternalChangeFactory;
 use Wikibase\Client\Specials\SpecialPagesWithBadges;
 use Wikibase\Client\Specials\SpecialUnconnectedPages;
+use Wikibase\Client\Specials\SpecialEntityUsage;
 use Wikibase\Client\WikibaseClient;
 use Wikibase\DataModel\Entity\EntityId;
 use Wikibase\Lib\AutoCommentFormatter;
@@ -473,6 +474,7 @@
        public static function onwgQueryPages( &$queryPages ) {
                $queryPages[] = array( SpecialUnconnectedPages::class, 
'UnconnectedPages' );
                $queryPages[] = array( SpecialPagesWithBadges::class, 
'PagesWithBadges' );
+               $queryPages[] = array( SpecialEntityUsage::class, 'EntityUsage' 
);
                return true;
        }
 
diff --git a/extensions/Wikibase/client/WikibaseClient.i18n.alias.php 
b/extensions/Wikibase/client/WikibaseClient.i18n.alias.php
index 9feeb67..893baf6 100644
--- a/extensions/Wikibase/client/WikibaseClient.i18n.alias.php
+++ b/extensions/Wikibase/client/WikibaseClient.i18n.alias.php
@@ -14,6 +14,7 @@
 
 /** English (English) */
 $specialPageAliases['en'] = array(
+       'EntityUsage' => array( 'EntityUsage', 'EntityUsageData' ),
        'PagesWithBadges' => array( 'PagesWithBadges', 'QueryBadges' ),
        'UnconnectedPages' => array( 'UnconnectedPages', 'WithoutConnection', 
'WithoutSitelinks' ),
 );
diff --git a/extensions/Wikibase/client/WikibaseClient.php 
b/extensions/Wikibase/client/WikibaseClient.php
index c6efd12..7b34a44 100644
--- a/extensions/Wikibase/client/WikibaseClient.php
+++ b/extensions/Wikibase/client/WikibaseClient.php
@@ -209,6 +209,7 @@
        // Special page registration
        $wgSpecialPages['UnconnectedPages'] = 
'Wikibase\Client\Specials\SpecialUnconnectedPages';
        $wgSpecialPages['PagesWithBadges'] = 
'Wikibase\Client\Specials\SpecialPagesWithBadges';
+       $wgSpecialPages['EntityUsage'] = 
'Wikibase\Client\Specials\SpecialEntityUsage';
        $wgHooks['wgQueryPages'][] = 'Wikibase\ClientHooks::onwgQueryPages';
 
        // Resource loader modules
diff --git a/extensions/Wikibase/client/i18n/en.json 
b/extensions/Wikibase/client/i18n/en.json
index a29af07..1af2235 100644
--- a/extensions/Wikibase/client/i18n/en.json
+++ b/extensions/Wikibase/client/i18n/en.json
@@ -91,6 +91,12 @@
        "wikibase-pageswithbadges-legend": "List of pages with a given badge",
        "wikibase-pageswithbadges-badge": "Badge:",
        "wikibase-pageswithbadges-submit": "Show pages",
+       "entityusage": "Entity Usage",
+       "entityusage-summary": "This page lists pages that use the given entity 
(e.g. Q42). The list is sorted by descending page ID, so that newer pages are 
listed first.",
+       "wikibase-entityusage-invalid-id": "$1 is not a valid item ID",
+       "wikibase-entityusage-legend": "List of pages that use a given entity",
+       "wikibase-entityusage-entity": "Entity:",
+       "wikibase-entityusage-submit": "Show pages",
        "wikibase-pageinfo-entity-id": "{{WBREPONAME}} item ID",
        "wikibase-pageinfo-entity-id-none": "None",
        "wikibase-pageinfo-entity-usage": "{{WBREPONAME}} entities used in this 
page",
diff --git a/extensions/Wikibase/client/i18n/qqq.json 
b/extensions/Wikibase/client/i18n/qqq.json
index 5ca87df..2743077 100644
--- a/extensions/Wikibase/client/i18n/qqq.json
+++ b/extensions/Wikibase/client/i18n/qqq.json
@@ -102,6 +102,12 @@
        "wikibase-pageswithbadges-legend": "Legend for the PagesWithBadges 
special page",
        "wikibase-pageswithbadges-badge": "Label for the input field to select 
the badge to filter by.\n{{Identical|Badge}}",
        "wikibase-pageswithbadges-submit": "Label for the button that activates 
the action",
+       "entityusage": "{{doc-special|EntityUsage}}",
+       "entityusage-summary": "Introductory text used on Special:EntityUsage.",
+       "wikibase-entityusage-invalid-id": "Error message when an invalid id is 
passed to the special page. Parameters:\n* $1 - the invalid ID",
+       "wikibase-entityusage-legend": "Legend for the EntityUsage special 
page",
+       "wikibase-entityusage-entity": "Label for the input field to select the 
entity to show.",
+       "wikibase-entityusage-submit": "Label for the button that activates the 
action",
        "wikibase-pageinfo-entity-id": "A link to the corresponding Wikibase 
Item",
        "wikibase-pageinfo-entity-id-none": "The page is not linked with a 
wikibase item.\n{{Identical|None}}",
        "wikibase-pageinfo-entity-usage": "Desciption in action=info about 
entities used in the page",
diff --git 
a/extensions/Wikibase/client/includes/Specials/SpecialEntityUsage.php 
b/extensions/Wikibase/client/includes/Specials/SpecialEntityUsage.php
new file mode 100644
index 0000000..496427c
--- /dev/null
+++ b/extensions/Wikibase/client/includes/Specials/SpecialEntityUsage.php
@@ -0,0 +1,216 @@
+<?php
+
+namespace Wikibase\Client\Specials;
+
+use HTMLForm;
+use Html;
+use InvalidArgumentException;
+use Linker;
+use QueryPage;
+use Skin;
+use Title;
+use Wikibase\Client\WikibaseClient;
+use Wikibase\Client\Usage\EntityUsage;
+use Wikibase\DataModel\Entity\ItemId;
+
+/**
+ * Get usage of any given entity.
+ *
+ * @since 0.5
+ *
+ * @license GPL-2.0+
+ * @author Amir Sarabadani (ladsgr...@gmail.com)
+ */
+class SpecialEntityUsage extends QueryPage {
+
+       /**
+        * @var ItemId|null
+        */
+       private $entityId;
+
+       /**
+        * @see SpecialPage::__construct
+        *
+        * @param string $name
+        */
+       public function __construct( $name = 'EntityUsage' ) {
+               parent::__construct( $name );
+       }
+
+       /**
+        * @see QueryPage::execute
+        *
+        * @param string $subPage
+        */
+       public function execute( $subPage ) {
+               $this->prepareParams( $subPage );
+
+               if ( $this->entityId !== null ) {
+                       parent::execute( $subPage );
+               } else {
+                       $this->setHeaders();
+                       $this->outputHeader();
+                       $this->getOutput()->addHTML( $this->getPageHeader() );
+               }
+       }
+
+       private function prepareParams( $subPage ) {
+               $entity = $this->getRequest()->getText( 'entity', $subPage );
+
+               if ( $entity ) {
+                       try {
+                               $this->entityId = new ItemId( $entity );
+                       } catch ( InvalidArgumentException $ex ) {
+                               $this->getOutput()->addHTML(
+                                       Html::element(
+                                               'p',
+                                               [
+                                                       'class' => 'error'
+                                               ],
+                                               $this->msg( 
'wikibase-entityusage-invalid-id', $entity )
+                                       )
+                               );
+                       }
+               }
+       }
+
+       /**
+        * @see QueryPage::getPageHeader
+        *
+        * @return string
+        */
+       public function getPageHeader() {
+               $formDescriptor = [
+                       'entity' => [
+                               'name' => 'entity',
+                               'type' => 'text',
+                               'id' => 'wb-entityusage-entity',
+                               'label-message' => 
'wikibase-entityusage-entity',
+                       ],
+                       'submit' => [
+                               'name' => '',
+                               'type' => 'submit',
+                               'id' => 'wikibase-entityusage-submit',
+                               'default' => $this->msg( 
'wikibase-entityusage-submit' )->text()
+                       ]
+               ];
+
+               if ( $this->entityId !== null ) {
+                       $formDescriptor['entity']['default'] = 
$this->entityId->getSerialization();
+               }
+
+               return HTMLForm::factory( 'inline', $formDescriptor, 
$this->getContext() )
+                       ->setMethod( 'get' )
+                       ->setWrapperLegendMsg( 'wikibase-entityusage-legend' )
+                       ->suppressDefaultSubmit()
+                       ->prepareForm()
+                       ->getHTML( '' );
+       }
+
+       /**
+        * @see QueryPage::getQueryInfo
+        *
+        * @return array[]
+        */
+       public function getQueryInfo() {
+               $joinConds = [ 'wbc_entity_usage' => [ 'JOIN', [ 'page_id = 
eu_page_id' ] ] ];
+               $conds = [ 'eu_entity_id' => 
$this->entityId->getSerialization() ];
+               $groupConcat = wfGetDB( DB_REPLICA )
+                       ->buildGroupConcatField( '|', 'wbc_entity_usage',
+                               'eu_aspect', $conds, $joinConds
+               );
+
+               return [
+                       'tables' => [
+                               'page',
+                               'wbc_entity_usage'
+                       ],
+                       'fields' => [
+                               'value' => 'page_id',
+                               'namespace' => 'page_namespace',
+                               'title' => 'page_title',
+                               'aspects' => $groupConcat,
+                               'eu_page_id',
+                       ],
+                       'conds' => $conds,
+                       'options' => ['GROUP BY' => 'eu_page_id' ],
+                       'join_conds' => $joinConds
+               ];
+       }
+
+       /**
+        * @see QueryPage::formatResult
+        *
+        * @param Skin $skin
+        * @param object $result
+        *
+        * @return string
+        */
+       public function formatResult( $skin, $row ) {
+               global $wgContLang;
+
+               $title = Title::makeTitleSafe( $row->namespace, $row->title );
+               $aspects = $this->formatAspects( $row->aspects );
+               if ( $title instanceof Title ) {
+                       $text = $wgContLang->convert( $title->getPrefixedText() 
);
+                       return Linker::link( $title, htmlspecialchars( $text ) 
) . ': ' . $aspects;
+               } else {
+                       return Html::element( 'span', [ 'class' => 
'mw-invalidtitle' ],
+                               Linker::getInvalidTitleDescription( 
$this->getContext(), $row->namespace, $row->title ) );
+               }
+       }
+
+       /**
+        * @param string $rowAspects
+        * @return string
+        */
+       public function formatAspects( $rowAspects ) {
+               $rowAspects = explode( '|', $rowAspects );
+               $aspects = [];
+
+               foreach ( $rowAspects as $aspect ) {
+                       $aspect = EntityUsage::splitAspectKey( $aspect );
+                       $aspects[] = $this->getContext()->msg(
+                               'wikibase-pageinfo-entity-usage-' . $aspect[0], 
$aspect[1] )->parse();
+               }
+
+               return $this->getContext()->getLanguage()->commaList( $aspects 
);
+       }
+
+       /**
+        * @see QueryPage::isSyndicated
+        *
+        * @return bool
+        */
+       public function isSyndicated() {
+               return false;
+       }
+
+       /**
+        * @see QueryPage::isCacheable
+        *
+        * @return bool
+        */
+       public function isCacheable() {
+               return false;
+       }
+
+       /**
+        * @see QueryPage::linkParameters
+        *
+        * @return array
+        */
+       public function linkParameters() {
+               return [ 'entity' => $this->entityId->getSerialization() ];
+       }
+
+       /**
+        * @see SpecialPage::getGroupName
+        *
+        * @return string
+        */
+       protected function getGroupName() {
+               return 'pages';
+       }
+
+}
diff --git 
a/extensions/Wikibase/client/tests/phpunit/includes/Specials/SpecialEntityUsageTest.php
 
b/extensions/Wikibase/client/tests/phpunit/includes/Specials/SpecialEntityUsageTest.php
new file mode 100644
index 0000000..320962e
--- /dev/null
+++ 
b/extensions/Wikibase/client/tests/phpunit/includes/Specials/SpecialEntityUsageTest.php
@@ -0,0 +1,85 @@
+<?php
+
+namespace Wikibase\Client\Tests\Specials;
+
+use FakeResultWrapper;
+use SpecialPageFactory;
+use SpecialPageTestBase;
+use Title;
+use WikiPage;
+use Wikibase\Client\Specials\SpecialEntityUsage;
+use Wikibase\DataModel\Entity\ItemId;
+use Wikibase\DataModel\Services\Lookup\LabelDescriptionLookup;
+use Wikibase\DataModel\Term\Term;
+use Wikibase\Lib\Store\LanguageFallbackLabelDescriptionLookupFactory;
+
+/**
+ * @covers Wikibase\Client\Specials\SpecialEntityUsage
+ *
+ * @group WikibaseClient
+ * @group SpecialPage
+ * @group WikibaseSpecialPage
+ * @group Wikibase
+ *
+ * @license GPL-2.0+
+ * @author Amir Sarabadani <ladsgr...@gmail.com>
+ */
+class SpecialEntityUsageTest extends SpecialPageTestBase {
+
+       protected function setUp() {
+               parent::setUp();
+       }
+
+       public function reallyDoQueryMock() {
+               $rows = [
+                       (object)[
+                               'value' => 11,
+                               'namespace' => 0,
+                               'title' => 'Tehran',
+                               'aspects' => 'S|O|L.fa',
+                               'eu_page_id' => 11,
+                               'eu_entity_id' => 'Q3',
+                       ],
+               ];
+               $res = new FakeResultWrapper( $rows );
+               return $res;
+       }
+
+       protected function newSpecialPage() {
+               $specialPage = $this->getMockBuilder( SpecialEntityUsage::class 
)
+                       ->setMethods( [ 'reallyDoQuery' ] )
+                       ->getMock();
+
+               $specialPage->expects( $this->any() )
+                       ->method( 'reallyDoQuery' )
+                       ->will( $this->returnValue( $this->reallyDoQueryMock() 
) );
+
+               return $specialPage;
+       }
+
+       public function testExecuteWithValidParam() {
+               list( $result, ) = $this->executeSpecialPage( 'Q3' );
+               $aspects = [
+                       wfMessage( 'wikibase-pageinfo-entity-usage-S' 
)->parse(),
+                       wfMessage( 'wikibase-pageinfo-entity-usage-O' 
)->parse(),
+                       wfMessage( 'wikibase-pageinfo-entity-usage-L', 'fa' 
)->parse(),
+               ];
+
+               $this->assertContains( 'Tehran', $result );
+               $this->assertNotContains( '<p class="error"', $result );
+               $expected = SpecialPageFactory::getLocalNameFor( 'EntityUsage', 
'Q3' );
+               $this->assertContains( $expected, $result );
+               $this->assertContains( implode( ", ", $aspects ), $result );
+       }
+
+       public function testExecuteWithInvalidParam() {
+               list( $result, ) = $this->executeSpecialPage( 'FooBar' );
+
+               $this->assertContains( '<p class="error"', $result );
+               $this->assertContains(
+                       wfMessage( 'wikibase-entityusage-invalid-id', 'FooBar' 
)->text(),
+                       $result
+               );
+       }
+
+}
diff --git 
a/extensions/Wikibase/view/resources/jquery/ui/jquery.ui.EditableTemplatedWidget.js
 
b/extensions/Wikibase/view/resources/jquery/ui/jquery.ui.EditableTemplatedWidget.js
index 5625a88..1b7ca24 100644
--- 
a/extensions/Wikibase/view/resources/jquery/ui/jquery.ui.EditableTemplatedWidget.js
+++ 
b/extensions/Wikibase/view/resources/jquery/ui/jquery.ui.EditableTemplatedWidget.js
@@ -61,16 +61,6 @@
        },
 
        /**
-        * Draws the widget according to whether it is in edit mode or not.
-        *
-        * @return {Object} jQuery.Promise
-        *         No resolved parameters.
-        *         Rejected parameters:
-        *         - {Error}
-        */
-       draw: util.abstractMember,
-
-       /**
         * Starts the widget's edit mode.
         *
         * @return {Object} jQuery.Promise
@@ -79,26 +69,22 @@
         *         - {Error}
         */
        startEditing: function() {
-               var deferred = $.Deferred();
-
                if ( this.isInEditMode() ) {
-                       return deferred.resolve().promise();
+                       return $.Deferred().resolve().promise();
                }
 
                var self = this;
 
-               self.element.addClass( 'wb-edit' );
+               this.element.addClass( 'wb-edit' );
 
-               this.draw()
+               return this._startEditing()
                .done( function() {
                        self._trigger( 'afterstartediting' );
-                       deferred.resolve();
-               } )
-               .fail( function( error ) {
-                       deferred.reject( error );
                } );
+       },
 
-               return deferred.promise();
+       _startEditing: function() {
+               return $.Deferred().resolve().promise();
        },
 
        /**
@@ -112,39 +98,25 @@
         *         - {Error}
         */
        stopEditing: function( dropValue ) {
-               var done = $.Deferred().resolve().promise();
                if ( !this.isInEditMode() ) {
-                       return done;
+                       return $.Deferred().resolve().promise();
                }
-               this._afterStopEditing( dropValue );
-               return done;
-       },
 
-       /**
-        * @param {boolean} dropValue
-        * @return {Object} jQuery.Promise
-        *         No resolved parameters.
-        *         Rejected parameters:
-        *         - {Error}
-        */
-       _afterStopEditing: function( dropValue ) {
-               var self = this,
-                       deferred = $.Deferred();
+               this.element.removeClass( 'wb-edit' );
 
-               self.element.removeClass( 'wb-edit' );
-
-               this.draw()
+               var self = this;
+               return this._stopEditing( dropValue )
                .done( function() {
                        self.enable();
                        self._trigger( 'afterstopediting', null, [dropValue] );
-                       deferred.resolve();
                } )
                .fail( function( error ) {
                        self.setError( error );
-                       deferred.reject( error );
                } );
+       },
 
-               return deferred.promise();
+       _stopEditing: function( dropValue ) {
+               return $.Deferred().resolve().promise();
        },
 
        /**
diff --git 
a/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.aliasesview.js
 
b/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.aliasesview.js
index df8a473..a7093f4 100644
--- 
a/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.aliasesview.js
+++ 
b/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.aliasesview.js
@@ -159,6 +159,16 @@
                } );
        },
 
+       _startEditing: function() {
+               // FIXME: This could be much faster
+               return this.draw();
+       },
+
+       _stopEditing: function() {
+               // FIXME: This could be much faster
+               return this.draw();
+       },
+
        /**
         * @inheritdoc
         * @protected
diff --git 
a/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.badgeselector.js
 
b/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.badgeselector.js
index 51dc2f5..a3425b8 100644
--- 
a/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.badgeselector.js
+++ 
b/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.badgeselector.js
@@ -5,7 +5,7 @@
 ( function( $, mw ) {
        'use strict';
 
-var PARENT = $.ui.TemplatedWidget;
+var PARENT = $.ui.EditableTemplatedWidget;
 
 /**
  * References one single $menu instance that is reused for all badgeselector 
instances.
@@ -16,7 +16,7 @@
 /**
  * Selector for toggling badges.
  * @since 0.5
- * @extends jQuery.ui.TemplatedWidget
+ * @extends jQuery.ui.EditableTemplatedWidget
  *
  * @option {string[]} [value]
  *         Item ids of badges currently assigned.
@@ -361,31 +361,18 @@
                }
        },
 
-       startEditing: function() {
-               if ( this.isInEditMode() ) {
-                       return;
-               }
-
-               this.element.addClass( 'wb-edit' );
-
+       _startEditing: function() {
                this._updateEmptyBadge();
-
-               this._trigger( 'afterstartediting' );
+               return $.Deferred().resolve().promise();
        },
 
        /**
         * @param {boolean} dropValue
         */
-       stopEditing: function( dropValue ) {
-               if ( !this.isInEditMode() ) {
-                       return;
-               }
-
+       _stopEditing: function( dropValue ) {
                if ( $menu ) {
                        $menu.hide();
                }
-
-               this.element.removeClass( 'wb-edit' );
 
                if ( !dropValue ) {
                        this._updateEmptyBadge();
@@ -396,14 +383,7 @@
                        // Reinitialize badges based on this.options.value
                        this._addBadges();
                }
-               this._trigger( 'afterstopediting', null, [dropValue] );
-       },
-
-       /**
-        * @return {boolean}
-        */
-       isInEditMode: function() {
-               return this.element.hasClass( 'wb-edit' );
+               return $.Deferred().resolve().promise();
        },
 
        /**
diff --git 
a/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.descriptionview.js
 
b/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.descriptionview.js
index 2e2f271..86da940 100644
--- 
a/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.descriptionview.js
+++ 
b/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.descriptionview.js
@@ -161,6 +161,16 @@
                return done;
        },
 
+       _startEditing: function() {
+               // FIXME: This could be much faster
+               return this.draw();
+       },
+
+       _stopEditing: function() {
+               // FIXME: This could be much faster
+               return this.draw();
+       },
+
        /**
         * @see jQuery.ui.TemplatedWidget._setOption
         */
diff --git 
a/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.entitytermsforlanguagelistview.js
 
b/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.entitytermsforlanguagelistview.js
index 41cd29e..fa3fd5d 100644
--- 
a/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.entitytermsforlanguagelistview.js
+++ 
b/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.entitytermsforlanguagelistview.js
@@ -6,12 +6,12 @@
 ( function( mw, wb, $ ) {
        'use strict';
 
-       var PARENT = $.ui.TemplatedWidget;
+       var PARENT = $.ui.EditableTemplatedWidget;
 
 /**
  * Displays multiple fingerprints (see 
jQuery.wikibase.entitytermsforlanguageview).
  * @since 0.5
- * @extends jQuery.ui.TemplatedWidget
+ * @extends jQuery.ui.EditableTemplatedWidget
  *
  * @option {Fingerprint} value
  *
@@ -60,11 +60,6 @@
         * @type {jQuery}
         */
        $entitytermsforlanguagelistviewMore: null,
-
-       /**
-        * @type {boolean}
-        */
-       _isInEditMode: false,
 
        /**
         * @type {Object} Map of language codes pointing to list items (in the 
form of jQuery nodes).
@@ -287,7 +282,7 @@
 
                Object.keys( this._getMoreLanguages() ).sort().forEach( 
function( languageCode ) {
                        var $item = listview.addItem( 
self._getValueForLanguage( languageCode ) );
-                       if ( self._isInEditMode ) {
+                       if ( self.isInEditMode() ) {
                                lia.liInstance( $item ).startEditing();
                        }
                        self._moreLanguagesItems[languageCode] = $item;
@@ -364,67 +359,23 @@
                };
        },
 
-       /**
-        * @return {boolean}
-        */
-       isEmpty: function() {
-               return !!this.$listview.data( 'listview' ).items().length;
-       },
-
-       startEditing: function() {
-               if ( this._isInEditMode ) {
-                       return;
-               }
-
-               this._isInEditMode = true;
-               this.element.addClass( 'wb-edit' );
-
+       _startEditing: function() {
+               var self = this;
                var listview = this.$listview.data( 'listview' );
-               listview.startEditing();
-
-               this.updateInputSize();
-
-               this._trigger( 'afterstartediting' );
+               return listview.startEditing().done( function() {
+                       self.updateInputSize();
+               } );
        },
 
        /**
         * @param {boolean} [dropValue]
         */
-       stopEditing: function( dropValue ) {
-               var deferred = $.Deferred();
-
-               if ( !this._isInEditMode ) {
-                       return deferred.resolve().promise();
-               }
-
-               this.disable();
-
+       _stopEditing: function( dropValue ) {
                var listview = this.$listview.data( 'listview' );
 
-               listview.value().forEach( function( entitytermsforlanguageview 
) {
-                       entitytermsforlanguageview.stopEditing( dropValue );
-               } );
-
-               this._afterStopEditing( dropValue );
-               deferred.resolve();
-               return deferred.promise();
-       },
-
-       /**
-        * @param {boolean} dropValue
-        */
-       _afterStopEditing: function( dropValue ) {
-               if ( !dropValue ) {
-                       this.options.value = this.value();
-               }
-               this._isInEditMode = false;
-               this.enable();
-               this.element.removeClass( 'wb-edit' );
-               this._trigger( 'afterstopediting', null, [dropValue] );
-       },
-
-       cancelEditing: function() {
-               this.stopEditing( true );
+               return $.when.apply( $, listview.value().map( function( 
entitytermsforlanguageview ) {
+                       return entitytermsforlanguageview.stopEditing( 
dropValue );
+               } ) );
        },
 
        /**
@@ -466,23 +417,8 @@
                }
        },
 
-       /**
-        * Applies/Removes error state.
-        *
-        * @param {Error} [error]
-        */
-       setError: function( error ) {
-               if ( error ) {
-                       this.element.addClass( 'wb-error' );
-                       this._trigger( 'toggleerror', null, [error] );
-               } else {
-                       this.removeError();
-                       this._trigger( 'toggleerror' );
-               }
-       },
-
        removeError: function() {
-               this.element.removeClass( 'wb-error' );
+               PARENT.prototype.removeError.call( this );
 
                var listview = this.$listview.data( 'listview' ),
                        lia = listview.listItemAdapter();
diff --git 
a/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.entitytermsforlanguageview.js
 
b/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.entitytermsforlanguageview.js
index b4e4a89..862907c 100644
--- 
a/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.entitytermsforlanguageview.js
+++ 
b/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.entitytermsforlanguageview.js
@@ -170,32 +170,24 @@
                } );
        },
 
-       draw: function() {
-               return $.Deferred().resolve().promise();
-       },
-
        /**
         * Puts the widget into edit mode.
         */
-       startEditing: function() {
-               if ( this.isInEditMode() ) {
-                       return $.Deferred().resolve().promise();
-               }
-
+       _startEditing: function() {
                this.$labelview.data( 'labelview' ).startEditing();
                this.$descriptionview.data( 'descriptionview' ).startEditing();
                this.$aliasesview.data( 'aliasesview' ).startEditing();
-               return PARENT.prototype.startEditing.call( this );
+               return $.Deferred().resolve().promise();
        },
 
        /**
         * @param {boolean} [dropValue]
         */
-       _afterStopEditing: function( dropValue ) {
+       _stopEditing: function( dropValue ) {
                this.$labelview.data( 'labelview' ).stopEditing( dropValue );
                this.$descriptionview.data( 'descriptionview' ).stopEditing( 
dropValue );
                this.$aliasesview.data( 'aliasesview' ).stopEditing( dropValue 
);
-               return PARENT.prototype._afterStopEditing.call( this, dropValue 
);
+               return $.Deferred().resolve().promise();
        },
 
        /**
diff --git 
a/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.entitytermsview.js
 
b/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.entitytermsview.js
index 022d770..895c3f3 100644
--- 
a/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.entitytermsview.js
+++ 
b/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.entitytermsview.js
@@ -337,23 +337,19 @@
                        } );
        },
 
-       /**
-        * @inheritdoc
-        */
-       startEditing: function() {
+       _startEditing: function() {
                this._getEntitytermsforlanguagelistview().startEditing();
-
-               return PARENT.prototype.startEditing.call( this );
+               return this.draw();
        },
 
        /**
         * @param {boolean} dropValue
         */
-       _afterStopEditing: function( dropValue ) {
+       _stopEditing: function( dropValue ) {
+               this.draw();
                var self = this;
                return this._getEntitytermsforlanguagelistview().stopEditing( 
dropValue ).done( function() {
                        self.notification();
-                       return PARENT.prototype._afterStopEditing.call( self );
                } );
        },
 
diff --git 
a/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.labelview.js
 
b/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.labelview.js
index c84f2c5..f94a4dd 100644
--- 
a/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.labelview.js
+++ 
b/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.labelview.js
@@ -168,15 +168,17 @@
                return deferred.resolve().promise();
        },
 
-       /**
-        * @inheritdoc
-        * @protected
-        */
-       _afterStopEditing: function( dropValue ) {
+       _startEditing: function() {
+               // FIXME: This could be much faster
+               return this.draw();
+       },
+
+       _stopEditing: function( dropValue ) {
                if ( dropValue && this.options.value.getText() === '' ) {
                        this.$text.children( '.' + this.widgetFullName + 
'-input' ).val( '' );
                }
-               return PARENT.prototype._afterStopEditing.call( this, dropValue 
);
+               // FIXME: This could be much faster
+               return this.draw();
        },
 
        /**
diff --git 
a/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.referenceview.js
 
b/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.referenceview.js
index d407806..162862e 100644
--- 
a/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.referenceview.js
+++ 
b/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.referenceview.js
@@ -1,13 +1,13 @@
 ( function( wb, $ ) {
        'use strict';
 
-       var PARENT = $.ui.TemplatedWidget;
+       var PARENT = $.ui.EditableTemplatedWidget;
 
 /**
  * View for displaying and editing `wikibase.datamodel.Reference` objects.
  * @see wikibase.datamodel.Reference
  * @class jQuery.wikibase.referenceview
- * @extends jQuery.ui.TemplatedWidget
+ * @extends jQuery.ui.EditableTemplatedWidget
  * @since 0.4
  * @license GPL-2.0+
  * @author H. Snater < mediaw...@snater.com >
@@ -17,6 +17,7 @@
  * @param {Object} options
  * @param {wikibase.datamodel.Reference|null} options.value
  * @param {Function} options.getListItemAdapter
+ * @param {Function} options.removeCallback
  */
 /**
  * @event afterstartediting
@@ -59,29 +60,28 @@
        },
 
        /**
-        * Whether the widget is currently in edit mode.
-        * @property {boolean} [_isInEditMode=false]
-        * @private
-        */
-       _isInEditMode: false,
-
-       /**
         * @inheritdoc
         * @protected
         *
         * @throws {Error} if a required option is not specified properly.
         */
        _create: function() {
-               if ( !this.options.getListItemAdapter ) {
+               if ( !this.options.getListItemAdapter || 
!this.options.removeCallback ) {
                        throw new Error( 'Required option not specified 
properly' );
                }
 
                PARENT.prototype._create.call( this );
 
+               var self = this;
                var listview;
                this.$listview.listview( {
                        listItemAdapter: this.options.getListItemAdapter( 
function( snaklistview ) {
                                listview.removeItem( snaklistview.element );
+                               if ( listview.items().length === 0 ) {
+                                       self.options.removeCallback();
+                               } else {
+                                       self._trigger( 'change' );
+                               }
                        } ),
                        value: this.options.value ? 
this.options.value.getSnaks().getGroupedSnakLists() : []
                } );
@@ -190,21 +190,12 @@
         *
         * @since 0.5
         */
-       startEditing: function() {
-               if ( this.isInEditMode() ) {
-                       return;
-               }
-
-               this.$listview.data( 'listview' ).startEditing();
-
+       _startEditing: function() {
                this._attachEditModeEventHandlers();
-
-               this.element.addClass( 'wb-edit' );
-               this._isInEditMode = true;
 
                this._snakListAdder = this.options.getAdder( 
this.enterNewItem.bind( this ), this.element );
 
-               this._trigger( 'afterstartediting' );
+               return this.$listview.data( 'listview' ).startEditing();
        },
 
        /**
@@ -212,23 +203,15 @@
         *
         * @since 0.5
         */
-       stopEditing: function() {
-               if ( !this.isInEditMode() ) {
-                       return;
-               }
+       _stopEditing: function() {
+               this._detachEditModeEventHandlers();
 
                this._snakListAdder.destroy();
                this._snakListAdder = null;
 
-               this._isInEditMode = false;
-               this.element.removeClass( 'wb-edit' );
-
-               this._detachEditModeEventHandlers();
-
                // FIXME: There should be a listview::stopEditing method
                this._stopEditingReferenceSnaks();
-
-               this._trigger( 'afterstopediting' );
+               return $.Deferred().resolve().promise();
        },
 
        /**
@@ -237,17 +220,6 @@
        _stopEditingReferenceSnaks: function() {
                var listview = this.$listview.data( 'listview' );
                listview.value( this.options.value ? 
this.options.value.getSnaks().getGroupedSnakLists() : [] );
-       },
-
-       /**
-        * Returns whether the widget is currently in edit mode.
-        *
-        * @since 0.5
-        *
-        * @return {boolean}
-        */
-       isInEditMode: function() {
-               return this._isInEditMode;
        },
 
        /**
@@ -277,16 +249,6 @@
                                $snakview.data( 'snakview' ).focus();
                        } );
                } );
-       },
-
-       /**
-        * Sets/removes error state from the widget.
-        *
-        * @param {boolean} error
-        */
-       setError: function( error ) {
-               this.element.toggleClass( 'wb-error', error );
-               this._trigger( 'toggleerror', null, [ error ] );
        },
 
        /**
diff --git 
a/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.sitelinkgroupview.js
 
b/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.sitelinkgroupview.js
index f8078c9..f56a7b3 100644
--- 
a/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.sitelinkgroupview.js
+++ 
b/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.sitelinkgroupview.js
@@ -201,25 +201,15 @@
                return value;
        },
 
-       /**
-        * @see jQuery.ui.EditableTemplatedWidget.startEditing
-        */
-       startEditing: function() {
-               var self = this;
-               return this.$sitelinklistview.data( 'sitelinklistview' 
).startEditing().done( function() {
-                       return PARENT.prototype.startEditing.call( self );
-               } );
+       _startEditing: function() {
+               return this.$sitelinklistview.data( 'sitelinklistview' 
).startEditing();
        },
 
-       /**
-        * @see jQuery.ui.EditableTemplatedWidget._afterStopEditing
-        */
-       _afterStopEditing: function( dropValue ) {
+       _stopEditing: function( dropValue ) {
                var self = this;
                return this.$sitelinklistview.data( 'sitelinklistview' 
).stopEditing( dropValue )
                .done( function() {
                        self.notification();
-                       return PARENT.prototype._afterStopEditing.call( self );
                } );
        },
 
diff --git 
a/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.sitelinklistview.js
 
b/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.sitelinklistview.js
index 36b8955..8b1bfda 100644
--- 
a/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.sitelinklistview.js
+++ 
b/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.sitelinklistview.js
@@ -303,10 +303,7 @@
                return $parenthesesMsg.contents();
        },
 
-       /**
-        * @see jQuery.ui.EditableTemplatedWidget.startEditing
-        */
-       startEditing: function() {
+       _startEditing: function() {
                var self = this;
 
                this._eventSingletonManager.register(
@@ -326,7 +323,7 @@
 
                self._startEditingInViewport();
 
-               return PARENT.prototype.startEditing.call( this );
+               return $.Deferred().resolve().promise();
        },
 
        _startEditingInViewport: function() {
@@ -372,21 +369,14 @@
                return PARENT.prototype.stopEditing.call( this, dropValue );
        },
 
-       /**
-        * @see jQuery.ui.EditableTemplatedWidget._afterStopEditing
-        */
-       _afterStopEditing: function( dropValue ) {
-               var self = this;
-
-               return PARENT.prototype._afterStopEditing.call( this, dropValue 
)
-                       .done( function() {
-                               self._refreshCounter();
-                               self._eventSingletonManager.unregister(
-                                       self,
-                                       window,
-                                       namespaceEventNames( 'scroll touchmove 
resize', self.widgetName )
-                               );
-                       } );
+       _stopEditing: function( dropValue ) {
+               this._refreshCounter();
+               this._eventSingletonManager.unregister(
+                       this,
+                       window,
+                       namespaceEventNames( 'scroll touchmove resize', 
this.widgetName )
+               );
+               return $.Deferred().resolve().promise();
        },
 
        _removeIncompleteSiteLinks: function() {
diff --git 
a/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.sitelinkview.js
 
b/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.sitelinkview.js
index bbe80a8..e739c3a 100644
--- 
a/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.sitelinkview.js
+++ 
b/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.sitelinkview.js
@@ -5,12 +5,12 @@
 ( function( mw, wb, $ ) {
        'use strict';
 
-       var PARENT = $.ui.TemplatedWidget;
+       var PARENT = $.ui.EditableTemplatedWidget;
 
 /**
  * Displays and allows editing a site link.
  * @since 0.5
- * @extends jQuery.ui.TemplatedWidget
+ * @extends jQuery.ui.EditableTemplatedWidget
  *
  * @option {wikibase.datamodel.SiteLink} [value]
  *         Default: null
@@ -72,11 +72,6 @@
        },
 
        /**
-        * @type {boolean}
-        */
-       _isInEditMode: false,
-
-       /**
         * @type {jQuery.wikibase.badgeselector|null}
         */
        _badgeselector: null,
@@ -133,7 +128,7 @@
                        this._siteLinkRemover = null;
                }
 
-               if ( this._isInEditMode ) {
+               if ( this.isInEditMode() ) {
                        var self = this;
 
                        this.element.one( this.widgetEventPrefix + 
'afterstopediting', function( event ) {
@@ -201,9 +196,7 @@
                        this._createBadgeSelector();
                }
 
-               this.element.toggleClass( 'wb-edit', this._isInEditMode );
-
-               if ( this._isInEditMode ) {
+               if ( this.isInEditMode() ) {
                        this._drawEditMode();
                }
        },
@@ -358,7 +351,7 @@
         * @return {boolean}
         */
        isEmpty: function() {
-               if ( !this._isInEditMode ) {
+               if ( !this.isInEditMode() ) {
                        return !this.options.value;
                }
 
@@ -370,19 +363,14 @@
        /**
         * Puts the widget into edit mode.
         */
-       startEditing: function() {
-               if ( this._isInEditMode ) {
-                       return;
-               }
-
-               this._isInEditMode = true;
+       _startEditing: function() {
                this._draw();
 
                if ( this.option( 'disabled' ) ) {
                        this._setState( 'disable' );
                }
 
-               this._trigger( 'afterstartediting' );
+               return $.Deferred().resolve().promise();
        },
 
        /**
@@ -395,35 +383,12 @@
         *         Rejected parameters:
         *         - {Error}
         */
-       stopEditing: function( dropValue ) {
-               var deferred = $.Deferred();
-
-               if ( !this._isInEditMode ) {
-                       return deferred.resolve().promise();
-               }
-
+       _stopEditing: function( dropValue ) {
                if ( this._badgeselector ) {
                        this._badgeselector.stopEditing( dropValue );
                }
-               this._afterStopEditing( dropValue );
 
-               return deferred.resolve().promise();
-       },
-
-       /**
-        * Callback tearing down edit mode.
-        *
-        * @param {boolean} dropValue
-        */
-       _afterStopEditing: function( dropValue ) {
-               if ( !dropValue ) {
-                       this.options.value = this.value();
-               }
-
-               this._isInEditMode = false;
-               this._draw();
-
-               this._trigger( 'afterstopediting', null, [dropValue] );
+               return $.Deferred().resolve().promise();
        },
 
        /**
@@ -442,7 +407,7 @@
         */
        value: function( siteLink ) {
                if ( siteLink === undefined ) {
-                       if ( !this._isInEditMode ) {
+                       if ( !this.isInEditMode() ) {
                                return this.options.value;
                        }
 
@@ -502,7 +467,7 @@
         * @param {string} state
         */
        _setState: function( state ) {
-               if ( this._isInEditMode ) {
+               if ( this.isInEditMode() ) {
                        var $siteInput = this.$siteId.find( 'input' ),
                                hasSiteId = !!( this.options.value && 
this.options.value.getSiteId() );
 
@@ -541,21 +506,6 @@
                        $siteselector.focus();
                } else {
                        this.element.focus();
-               }
-       },
-
-       /**
-        * Applies/Removes error state.
-        *
-        * @param {Error} [error]
-        */
-       setError: function( error ) {
-               if ( error ) {
-                       this.element.addClass( 'wb-error' );
-                       this._trigger( 'toggleerror', null, [error] );
-               } else if ( this.element.hasClass( 'wb-error' ) ) {
-                       this.element.removeClass( 'wb-error' );
-                       this._trigger( 'toggleerror' );
                }
        }
 
diff --git 
a/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.snaklistview.js
 
b/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.snaklistview.js
index adb0a50..01eebf0 100644
--- 
a/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.snaklistview.js
+++ 
b/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.snaklistview.js
@@ -1,13 +1,13 @@
 ( function( wb, $ ) {
        'use strict';
 
-       var PARENT = $.ui.TemplatedWidget;
+       var PARENT = $.ui.EditableTemplatedWidget;
 
 /**
  * View for displaying and editing a `wikibase.datamodel.SnakList` object.
  * @see wikibase.datamodel.SnakList
  * @class jQuery.wikibase.snaklistview
- * @extends jQuery.ui.TemplatedWidget
+ * @extends jQuery.ui.EditableTemplatedWidget
  * @uses jQuery.wikibase.listview
  * @since 0.4
  * @license GPL-2.0+
@@ -76,12 +76,6 @@
         * @private
         */
        _lia: null,
-
-       /**
-        * Whether the `snaklistview` currently is in edit mode.
-        * @property {boolean} [_isInEditMode=false]
-        */
-       _isInEditMode: false,
 
        /**
         * @inheritdoc
@@ -174,17 +168,8 @@
        /**
         * Starts the widget's edit mode.
         */
-       startEditing: function() {
-               if ( this._isInEditMode ) {
-                       return;
-               }
-
-               this._listview.startEditing();
-
-               this.element.addClass( 'wb-edit' );
-               this._isInEditMode = true;
-
-               this._trigger( 'afterstartediting' );
+       _startEditing: function() {
+               return this._listview.startEditing();
        },
 
        /**
@@ -193,14 +178,7 @@
         * @param {boolean} [dropValue=false] If `true`, the widget's value 
will be reset to the one from
         *        before edit mode was started
         */
-       stopEditing: function( dropValue ) {
-               if ( !this._isInEditMode ) {
-                       return;
-               }
-
-               this.element.removeClass( 'wb-error' );
-               this.disable();
-
+       _stopEditing: function( dropValue ) {
                if ( dropValue ) {
                        // If the whole item was pending, remove the whole list 
item. This has to be
                        // performed in the widget using the snaklistview.
@@ -216,20 +194,7 @@
                                snakview.options.locked.property = true;
                        } );
                }
-
-               this.enable();
-
-               this.element.removeClass( 'wb-edit' );
-               this._isInEditMode = false;
-
-               this._trigger( 'afterstopediting', null, [ dropValue ] );
-       },
-
-       /**
-        * Cancels editing. (Short-cut for `stopEditing( true )`.)
-        */
-       cancelEditing: function() {
-               return this.stopEditing( true ); // stop editing and drop value
+               return $.Deferred().resolve().promise();
        },
 
        /**
@@ -271,13 +236,6 @@
                return this._listview.enterNewItem().done( function() {
                        self.startEditing();
                } );
-       },
-
-       /**
-        * @return {boolean}
-        */
-       isInEditMode: function() {
-               return this._isInEditMode;
        },
 
        /**
diff --git 
a/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.statementlistview.js
 
b/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.statementlistview.js
index 1c01894..2464492 100644
--- 
a/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.statementlistview.js
+++ 
b/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.statementlistview.js
@@ -181,15 +181,6 @@
        },
 
        /**
-        * Returns whether the widget currently features any `statementview` 
widgets.
-        *
-        * @return {boolean}
-        */
-       isEmpty: function() {
-               return !this._listview.items().length;
-       },
-
-       /**
         * Adds a new, pending `statementview` to the `statementlistview`.
         *
         * @see jQuery.wikibase.listview.enterNewItem
diff --git 
a/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.statementview.RankSelector.js
 
b/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.statementview.RankSelector.js
index 65af667..79cb7a0 100644
--- 
a/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.statementview.RankSelector.js
+++ 
b/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.statementview.RankSelector.js
@@ -312,15 +312,16 @@
                        return $.Deferred().resolve().promise();
                },
 
-               /**
-                * @inheritdoc
-                */
-               stopEditing: function( dropValue ) {
+               _startEditing: function() {
+                       return this.draw();
+               },
+
+               _stopEditing: function( dropValue ) {
                        // Hide the menu the rank selector currently references 
to:
                        if ( $menu && $menu.data( this.widgetName ) === this ) {
                                $menu.hide();
                        }
-                       return PARENT.prototype.stopEditing.call( this, 
dropValue );
+                       return this.draw();
                }
 
        } );
diff --git 
a/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.statementview.js
 
b/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.statementview.js
index eafc65f..bbff224 100644
--- 
a/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.statementview.js
+++ 
b/extensions/Wikibase/view/resources/jquery/wikibase/jquery.wikibase.statementview.js
@@ -597,16 +597,8 @@
                this.$refsHeading.find( '.ui-toggler-label' ).empty().append( 
$counterMsg );
        },
 
-       /**
-        * @inheritdoc
-        */
-       startEditing: function() {
+       _startEditing: function() {
                var self = this;
-
-               if ( this.isInEditMode() ) {
-                       return $.Deferred().resolve().promise();
-               }
-
                this._qualifierAdder = this.options.getAdder(
                        function() {
                                var listview = self._qualifiers;
@@ -621,18 +613,14 @@
                        mw.msg( 'wikibase-addqualifier' )
                );
 
-               // We need to initialize the main snak before calling 
PARENT::startEditing,
-               // since that triggers 'afterstartediting' which tries to set 
focus into
-               // the main snak
-               this._createMainSnak();
-               return this._mainSnakSnakView.startEditing().then( function() {
-                       // PARENT::startEditing calls this.draw
-                       return PARENT.prototype.startEditing.call( self );
-               } ).then( function() {
-                       self._rankSelector.startEditing();
-                       self._qualifiers.startEditing();
-                       self._startEditingReferences();
-               } );
+               return $.when(
+                       this._createMainSnak(),
+                       this.draw(),
+                       this._mainSnakSnakView.startEditing(),
+                       this._rankSelector.startEditing(),
+                       this._qualifiers.startEditing(),
+                       this._startEditingReferences()
+               );
        },
 
        /**
@@ -653,19 +641,15 @@
                }
        },
 
-       /**
-        * @inheritdoc
-        * @protected
-        */
-       _afterStopEditing: function( dropValue ) {
-               this._mainSnakSnakView.stopEditing( dropValue );
-               this._stopEditingQualifiers( dropValue );
-               this._rankSelector.stopEditing( dropValue );
-
+       _stopEditing: function( dropValue ) {
                // FIXME: Should not be necessary if _setOption would do the 
right thing for values
                this._recreateReferences();
+               this._stopEditingQualifiers( dropValue );
 
-               return PARENT.prototype._afterStopEditing.call( this, dropValue 
);
+               return $.when(
+                       this._mainSnakSnakView.stopEditing( dropValue ),
+                       this._rankSelector.stopEditing( dropValue )
+               );
        },
 
        /**
diff --git a/extensions/Wikibase/view/resources/jquery/wikibase/resources.php 
b/extensions/Wikibase/view/resources/jquery/wikibase/resources.php
index 4b58509..d3c1a46 100644
--- a/extensions/Wikibase/view/resources/jquery/wikibase/resources.php
+++ b/extensions/Wikibase/view/resources/jquery/wikibase/resources.php
@@ -45,7 +45,7 @@
                        ),
                        'dependencies' => array(
                                'jquery.ui.menu',
-                               'jquery.ui.TemplatedWidget',
+                               'jquery.ui.EditableTemplatedWidget',
                                'wikibase.templates',
                        ),
                ),
@@ -184,7 +184,7 @@
                                
'themes/default/jquery.wikibase.entitytermsforlanguagelistview.css',
                        ),
                        'dependencies' => array(
-                               'jquery.ui.TemplatedWidget',
+                               'jquery.ui.EditableTemplatedWidget',
                                'jquery.wikibase.entitytermsforlanguageview',
                                'wikibase.getLanguageNameByCode',
                        ),
@@ -206,7 +206,7 @@
                                
'themes/default/jquery.wikibase.entitytermsforlanguageview.css',
                        ),
                        'dependencies' => array(
-                               'jquery.ui.TemplatedWidget',
+                               'jquery.ui.EditableTemplatedWidget',
                                'jquery.wikibase.aliasesview',
                                'jquery.wikibase.descriptionview',
                                'jquery.wikibase.labelview',
@@ -286,6 +286,7 @@
                        ),
                        'dependencies' => array(
                                'jquery.removeClassByRegex',
+                               'jquery.ui.EditableTemplatedWidget',
                                'jquery.wikibase.listview',
                                'wikibase.datamodel',
                        ),
@@ -315,7 +316,7 @@
                        'dependencies' => array(
                                'jquery.makeCollapsible',
                                'jquery.sticknode',
-                               'jquery.ui.TemplatedWidget',
+                               'jquery.ui.EditableTemplatedWidget',
                                'jquery.util.EventSingletonManager',
                                'mediawiki.jqueryMsg', // for {{plural}} and 
{{gender}} support in messages
                                'wikibase.buildErrorOutput',
@@ -358,7 +359,7 @@
                                
'themes/default/jquery.wikibase.sitelinkview.css',
                        ),
                        'dependencies' => array(
-                               'jquery.ui.TemplatedWidget',
+                               'jquery.ui.EditableTemplatedWidget',
                                'jquery.util.EventSingletonManager',
                                'jquery.wikibase.badgeselector',
                                'jquery.wikibase.pagesuggester',
@@ -382,7 +383,7 @@
                                'jquery.wikibase.snaklistview.js',
                        ),
                        'dependencies' => array(
-                               'jquery.ui.TemplatedWidget',
+                               'jquery.ui.EditableTemplatedWidget',
                                'jquery.wikibase.listview',
                                'wikibase.datamodel.Snak',
                                'wikibase.datamodel.SnakList',
diff --git 
a/extensions/Wikibase/view/resources/jquery/wikibase/snakview/resources.php 
b/extensions/Wikibase/view/resources/jquery/wikibase/snakview/resources.php
index 37dd29b..d560ddb 100644
--- a/extensions/Wikibase/view/resources/jquery/wikibase/snakview/resources.php
+++ b/extensions/Wikibase/view/resources/jquery/wikibase/snakview/resources.php
@@ -27,8 +27,8 @@
                        'dependencies' => array(
                                'dataValues.DataValue',
                                'jquery.event.special.eachchange',
+                               'jquery.ui.EditableTemplatedWidget',
                                'jquery.ui.position',
-                               'jquery.ui.TemplatedWidget',
                                'jquery.wikibase.entityselector',
                                'jquery.wikibase.snakview.variations',
                                'jquery.wikibase.snakview.ViewState',
diff --git 
a/extensions/Wikibase/view/resources/jquery/wikibase/snakview/snakview.js 
b/extensions/Wikibase/view/resources/jquery/wikibase/snakview/snakview.js
index 6e4ecf1..79754b7 100644
--- a/extensions/Wikibase/view/resources/jquery/wikibase/snakview/snakview.js
+++ b/extensions/Wikibase/view/resources/jquery/wikibase/snakview/snakview.js
@@ -9,13 +9,13 @@
        // Erase existing object to prevent jQuery.Widget detecting an existing 
constructor:
        delete $.wikibase.snakview;
 
-       var PARENT = $.ui.TemplatedWidget;
+       var PARENT = $.ui.EditableTemplatedWidget;
 
 /**
  * View for displaying and editing `wikibase.datamodel.Snak` objects.
  * @see wikibase.datamodel.Snak
  * @class jQuery.wikibase.snakview
- * @extends jQuery.ui.TemplatedWidget
+ * @extends jQuery.ui.EditableTemplatedWidget
  * @since 0.3
  * @author Daniel Werner < daniel.wer...@wikimedia.de >
  * @author H. Snater < mediaw...@snater.com >
@@ -112,12 +112,6 @@
         * @private
         */
        _cachedValues: null,
-
-       /**
-        * @property {boolean}
-        * @private
-        */
-       _isInEditMode: false,
 
        /**
         * Whether then `snakview`'s value is regarded "valid" at the moment.
@@ -295,38 +289,20 @@
                $.Widget.prototype.destroy.call( this );
        },
 
-       /**
-        * Starts the widget's edit mode.
-        *
-        * @return {Object} jQuery.Promise
-        * @return {Function} return.done
-        * @return {Function} return.fail
-        */
-       startEditing: function() {
+       _startEditing: function() {
                var deferred = $.Deferred();
-
-               if ( this.isInEditMode() ) {
-                       return deferred.resolve().promise();
-               }
-
-               var self = this;
-
-               this._isInEditMode = true;
-
                if ( this.options.getSnakRemover ) {
                        this._snakRemover = this.options.getSnakRemover( 
this.element );
                }
 
                if ( this._variation ) {
                        $( this._variation ).one( 'afterstartediting', 
function() {
-                               self._trigger( 'afterstartediting' );
                                deferred.resolve();
                        } );
                        this.draw();
                        this._variation.startEditing();
                } else {
                        this.draw();
-                       this._trigger( 'afterstartediting' );
                        deferred.resolve();
                }
                return deferred.promise();
@@ -354,47 +330,20 @@
         * @param {boolean} [dropValue=false] If `true`, the widget's value 
will be reset to the one
         *        from before edit mode was started.
         */
-       stopEditing: function( dropValue ) {
-               if ( !this.isInEditMode() ) {
-                       return;
-               }
-
+       _stopEditing: function( dropValue ) {
                if ( this._snakRemover ) {
                        this._snakRemover.destroy();
                        this._snakRemover = null;
                }
 
-               var snak = this.snak();
-
-               this._isInEditMode = false;
-
                if ( this._variation ) {
                        this._variation.stopEditing( dropValue );
-
-                       if ( !dropValue ) {
-                               // TODO: "this.snak( this.snak() )" is supposed 
to work to update the Snak. However,
-                               // the Variation asking the ValueView returns 
null as soon as edit mode is left.
-                               this.snak( snak );
-                       }
                }
-
-               if ( !this._variation || dropValue ) {
-                       this.value( this.options.value );
-               }
-
-               // TODO: Should throw an error somewhere when trying to leave 
edit mode while this.snak()
-               //  still returns null.
+               this.drawSnakTypeSelector();
 
                this.element.off( 'keydown.' + this.widgetName );
 
-               this._trigger( 'afterstopediting', null, [dropValue] );
-       },
-
-       /**
-        * Cancels editing. (Short-cut for `stopEditing( true )`.)
-        */
-       cancelEditing: function() {
-               return this.stopEditing( true );
+               return $.Deferred().resolve().promise();
        },
 
        /**
@@ -413,13 +362,6 @@
                if ( this._variation ) {
                        this._trigger( 'change' );
                }
-       },
-
-       /**
-        * @return {boolean}
-        */
-       isInEditMode: function() {
-               return this._isInEditMode;
        },
 
        /**
diff --git a/extensions/Wikibase/view/resources/wikibase/view/ViewFactory.js 
b/extensions/Wikibase/view/resources/wikibase/view/ViewFactory.js
index 568e1c8..5cc13c1 100644
--- a/extensions/Wikibase/view/resources/wikibase/view/ViewFactory.js
+++ b/extensions/Wikibase/view/resources/wikibase/view/ViewFactory.js
@@ -475,7 +475,11 @@
 
        SELF.prototype.getReferenceView = function( startEditingCallback, 
removeCallback, value, $dom ) {
                var structureEditorFactory = this._structureEditorFactory;
-               var view = this._getView(
+               var view;
+               var doRemove = function() {
+                       return removeCallback( view );
+               };
+               view = this._getView(
                        'referenceview',
                        $dom,
                        {
@@ -484,9 +488,10 @@
                                getListItemAdapter: 
this.getListItemAdapterForSnakListView.bind( this, startEditingCallback ),
                                getReferenceRemover: function( $dom ) {
                                        return 
structureEditorFactory.getRemover( function() {
-                                               return 
startEditingCallback().then( function() { return removeCallback( view ); } );
+                                               return 
startEditingCallback().then( doRemove );
                                        }, $dom );
-                               }
+                               },
+                               removeCallback: doRemove
                        }
                );
                return view;
diff --git 
a/extensions/Wikibase/view/tests/qunit/jquery/wikibase/jquery.wikibase.referenceview.tests.js
 
b/extensions/Wikibase/view/tests/qunit/jquery/wikibase/jquery.wikibase.referenceview.tests.js
index db8c673..58f5e69 100644
--- 
a/extensions/Wikibase/view/tests/qunit/jquery/wikibase/jquery.wikibase.referenceview.tests.js
+++ 
b/extensions/Wikibase/view/tests/qunit/jquery/wikibase/jquery.wikibase.referenceview.tests.js
@@ -15,9 +15,6 @@
                                        }
                                } ).promise();
                        };
-                       this.isValid = function() {
-                               return false;
-                       };
                        this.stopEditing = function() {};
                        this.value = function() {
                                return this.options.value;
@@ -40,12 +37,15 @@
                        },
                        getReferenceRemover: function() {
                                return {
-                                       destroy: function() {}
+                                       destroy: function() {},
+                                       disable: function() {},
+                                       enable: function() {}
                                };
                        },
                        getListItemAdapter: function() {
                                return listItemAdapter;
-                       }
+                       },
+                       removeCallback: function() {}
                }, options );
 
                return $( '<div/>' )
diff --git 
a/extensions/Wikibase/view/tests/qunit/jquery/wikibase/jquery.wikibase.sitelinklistview.tests.js
 
b/extensions/Wikibase/view/tests/qunit/jquery/wikibase/jquery.wikibase.sitelinklistview.tests.js
index efd4929..8a9398b 100644
--- 
a/extensions/Wikibase/view/tests/qunit/jquery/wikibase/jquery.wikibase.sitelinklistview.tests.js
+++ 
b/extensions/Wikibase/view/tests/qunit/jquery/wikibase/jquery.wikibase.sitelinklistview.tests.js
@@ -177,17 +177,6 @@
 
        sitelinklistview.enterNewItem();
 
-       var listview = sitelinklistview.$listview.data( 'listview' ),
-               lia = listview.listItemAdapter(),
-               sitelinkview = lia.liInstance( listview.items().first() );
-
-       sitelinkview.isEmpty = function() {
-               return false;
-       };
-       sitelinkview.isValid = function() {
-               return false;
-       };
-
        assert.strictEqual(
                sitelinklistview.value().length,
                0,
@@ -371,12 +360,16 @@
        sitelinklistview.enterNewItem();
 
        var listview = sitelinklistview.$listview.data( 'listview' ),
-               $sitelinkview = listview.items().first();
+               sitelinkview = listview.value()[0];
+
+       sitelinkview.isEmpty = function() {
+               return true;
+       };
 
        assert.equal( listview.items().length, 2 );
        var e = $.Event( 'keydown' );
        e.which = e.keyCode = $.ui.keyCode.BACKSPACE;
-       $sitelinkview.trigger( e );
+       sitelinkview.element.trigger( e );
 
        assert.equal( listview.items().length, 1 );
 } );
diff --git 
a/extensions/Wikibase/view/tests/qunit/jquery/wikibase/jquery.wikibase.snaklistview.tests.js
 
b/extensions/Wikibase/view/tests/qunit/jquery/wikibase/jquery.wikibase.snaklistview.tests.js
index 8137212..0662731 100644
--- 
a/extensions/Wikibase/view/tests/qunit/jquery/wikibase/jquery.wikibase.snaklistview.tests.js
+++ 
b/extensions/Wikibase/view/tests/qunit/jquery/wikibase/jquery.wikibase.snaklistview.tests.js
@@ -25,7 +25,6 @@
                        }
                        return _value;
                };
-               this.isValid = function() {};
                this.startEditing = function() {
                        this._trigger( 'change' );
                        this._trigger( 'afterstartediting' );
@@ -383,25 +382,6 @@
                        null,
                        'Snaklistview is not valid due to pending value.'
                );
-       } );
-
-       QUnit.test( 'cancelEditing()', function( assert ) {
-               assert.expect( 1 );
-               var $node = createSnaklistview(),
-                       snaklistview = $node.data( 'snaklistview' );
-
-               // Since cancelEditing is just a short-cut, there is no need 
for particular testing expect
-               // for verifying the actual short-cut behaviour.
-               snaklistview.stopEditing = function( dropValue ) {
-                       assert.strictEqual(
-                               dropValue,
-                               true,
-                               'Called stopEditing with dropValue flag set to 
TRUE.'
-                       );
-               };
-
-               snaklistview.startEditing();
-               snaklistview.cancelEditing();
        } );
 
        QUnit.test( 'Stopping edit mode dropping value', function( assert ) {
diff --git 
a/extensions/Wikibase/view/tests/qunit/jquery/wikibase/jquery.wikibase.statementlistview.tests.js
 
b/extensions/Wikibase/view/tests/qunit/jquery/wikibase/jquery.wikibase.statementlistview.tests.js
index 607db28..ba3a7a7 100644
--- 
a/extensions/Wikibase/view/tests/qunit/jquery/wikibase/jquery.wikibase.statementlistview.tests.js
+++ 
b/extensions/Wikibase/view/tests/qunit/jquery/wikibase/jquery.wikibase.statementlistview.tests.js
@@ -140,51 +140,6 @@
        );
 } );
 
-QUnit.test( 'isEmpty()', function( assert ) {
-       assert.expect( 4 );
-       var $statementlistview = createStatementlistview(),
-               statementlistview = $statementlistview.data( 
'statementlistview' );
-
-       assert.ok(
-               statementlistview.isEmpty(),
-               'Verified isEmpty() returning TRUE when widget has been 
initialized with an empty '
-                       + 'StatementList.'
-       );
-
-       $statementlistview = createStatementlistview( {
-               value: new wb.datamodel.StatementList( [
-                       new wb.datamodel.Statement( new wb.datamodel.Claim(
-                                       new wb.datamodel.PropertyNoValueSnak( 
'P1' )
-                       ) )
-               ] )
-       } );
-       statementlistview = $statementlistview.data( 'statementlistview' );
-
-       assert.ok(
-               !statementlistview.isEmpty(),
-               'Verified isEmpty() returning FALSE when widget has been 
initialized with a filled '
-                       + 'StatmentList.'
-       );
-
-       statementlistview.value( new wb.datamodel.StatementList() );
-
-       assert.ok(
-               statementlistview.isEmpty(),
-               'Verified isEmpty() returning TRUE after setting an empty 
StatementList.'
-       );
-
-       statementlistview.value( new wb.datamodel.StatementList( [
-               new wb.datamodel.Statement( new wb.datamodel.Claim(
-                       new wb.datamodel.PropertyNoValueSnak( 'P2' )
-               ) )
-       ] ) );
-
-       assert.ok(
-               !statementlistview.isEmpty(),
-               'Verified isEmpty() returning FALSE after setting an filled 
StatementList.'
-       );
-} );
-
 QUnit.test( 'enterNewItem', function( assert ) {
        assert.expect( 2 );
        var $statementlistview = createStatementlistview(),
diff --git 
a/extensions/Wikibase/view/tests/qunit/wikibase/view/ToolbarViewController.tests.js
 
b/extensions/Wikibase/view/tests/qunit/wikibase/view/ToolbarViewController.tests.js
index f94ceb3..22aac99 100644
--- 
a/extensions/Wikibase/view/tests/qunit/wikibase/view/ToolbarViewController.tests.js
+++ 
b/extensions/Wikibase/view/tests/qunit/wikibase/view/ToolbarViewController.tests.js
@@ -32,7 +32,6 @@
                                on: function() {}
                        },
                        enable: function() {},
-                       isValid: function() {},
                        setError: function() {},
                        startEditing: function() {
                                return $.Deferred();
diff --git 
a/extensions/Wikibase/view/tests/qunit/wikibase/view/ViewFactory.tests.js 
b/extensions/Wikibase/view/tests/qunit/wikibase/view/ViewFactory.tests.js
index fc4b148..e7f4b14 100644
--- a/extensions/Wikibase/view/tests/qunit/wikibase/view/ViewFactory.tests.js
+++ b/extensions/Wikibase/view/tests/qunit/wikibase/view/ViewFactory.tests.js
@@ -377,9 +377,11 @@
                sinon.assert.calledWith(
                        referenceview,
                        sinon.match( {
-                               value: value || null,
+                               getAdder: sinon.match.func,
                                getListItemAdapter: sinon.match.func,
-                               getReferenceRemover: sinon.match.func
+                               getReferenceRemover: sinon.match.func,
+                               removeCallback: sinon.match.func,
+                               value: value || null
                        } )
                );
 
diff --git a/vendor/composer/autoload_classmap.php 
b/vendor/composer/autoload_classmap.php
index 48b58b5..db2aacb 100644
--- a/vendor/composer/autoload_classmap.php
+++ b/vendor/composer/autoload_classmap.php
@@ -454,6 +454,7 @@
     'Wikibase\\Client\\RepoItemLinkGenerator' => $baseDir . 
'/extensions/Wikibase/client/includes/RepoItemLinkGenerator.php',
     'Wikibase\\Client\\RepoLinker' => $baseDir . 
'/extensions/Wikibase/client/includes/RepoLinker.php',
     'Wikibase\\Client\\Serializer\\ClientEntitySerializer' => $baseDir . 
'/extensions/Wikibase/client/includes/Serializer/ClientEntitySerializer.php',
+    'Wikibase\\Client\\Specials\\SpecialEntityUsage' => $baseDir . 
'/extensions/Wikibase/client/includes/Specials/SpecialEntityUsage.php',
     'Wikibase\\Client\\Specials\\SpecialPagesWithBadges' => $baseDir . 
'/extensions/Wikibase/client/includes/Specials/SpecialPagesWithBadges.php',
     'Wikibase\\Client\\Specials\\SpecialUnconnectedPages' => $baseDir . 
'/extensions/Wikibase/client/includes/Specials/SpecialUnconnectedPages.php',
     'Wikibase\\Client\\Store\\AddUsagesForPageJob' => $baseDir . 
'/extensions/Wikibase/client/includes/Store/AddUsagesForPageJob.php',
@@ -532,6 +533,7 @@
     'Wikibase\\Client\\Tests\\RepoLinkerTest' => $baseDir . 
'/extensions/Wikibase/client/tests/phpunit/includes/RepoLinkerTest.php',
     'Wikibase\\Client\\Tests\\Serializer\\ClientEntitySerializerTest' => 
$baseDir . 
'/extensions/Wikibase/client/tests/phpunit/includes/Serializer/ClientEntitySerializerTest.php',
     'Wikibase\\Client\\Tests\\SiteLinkCommentCreatorTest' => $baseDir . 
'/extensions/Wikibase/client/tests/phpunit/includes/SiteLinkCommentCreatorTest.php',
+    'Wikibase\\Client\\Tests\\Specials\\SpecialEntityUsageTest' => $baseDir . 
'/extensions/Wikibase/client/tests/phpunit/includes/Specials/SpecialEntityUsageTest.php',
     'Wikibase\\Client\\Tests\\Specials\\SpecialPagesWithBadgesTest' => 
$baseDir . 
'/extensions/Wikibase/client/tests/phpunit/includes/Specials/SpecialPagesWithBadgesTest.php',
     'Wikibase\\Client\\Tests\\Specials\\SpecialUnconnectedPagesTest' => 
$baseDir . 
'/extensions/Wikibase/client/tests/phpunit/includes/Specials/SpecialUnconnectedPagesTest.php',
     'Wikibase\\Client\\Tests\\Store\\Sql\\BulkSubscriptionUpdaterTest' => 
$baseDir . 
'/extensions/Wikibase/client/tests/phpunit/includes/Store/Sql/BulkSubscriptionUpdaterTest.php',
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
index d9b512d..991f687 100644
--- a/vendor/composer/installed.json
+++ b/vendor/composer/installed.json
@@ -1354,12 +1354,12 @@
         "source": {
             "type": "git",
             "url": 
"https://github.com/wikimedia/mediawiki-extensions-Wikibase.git";,
-            "reference": "bee7c4389ddd810ba119b0d37df97d2daf9df0f9"
+            "reference": "3dcac6c817c4ff350345f78fb902b57bf49e2a45"
         },
         "dist": {
             "type": "zip",
-            "url": 
"https://api.github.com/repos/wikimedia/mediawiki-extensions-Wikibase/zipball/bee7c4389ddd810ba119b0d37df97d2daf9df0f9";,
-            "reference": "bee7c4389ddd810ba119b0d37df97d2daf9df0f9",
+            "url": 
"https://api.github.com/repos/wikimedia/mediawiki-extensions-Wikibase/zipball/3dcac6c817c4ff350345f78fb902b57bf49e2a45";,
+            "reference": "3dcac6c817c4ff350345f78fb902b57bf49e2a45",
             "shasum": ""
         },
         "require": {
@@ -1392,7 +1392,7 @@
             "jakub-onderka/php-parallel-lint": "0.9.2",
             "mediawiki/mediawiki-codesniffer": "0.4.0|0.5.0"
         },
-        "time": "2016-09-16 09:13:26",
+        "time": "2016-09-16 18:30:22",
         "type": "mediawiki-extension",
         "installation-source": "dist",
         "autoload": {

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

Gerrit-MessageType: merged
Gerrit-Change-Id: Ida781e06b609317b0b7ec1b80d53e16bd843ebd4
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Wikidata
Gerrit-Branch: master
Gerrit-Owner: WikidataBuilder <wikidata-servi...@wikimedia.de>
Gerrit-Reviewer: Aude <aude.w...@gmail.com>
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