jenkins-bot has submitted this change and it was merged. (
https://gerrit.wikimedia.org/r/359471 )
Change subject: Make statements on senses editable
......................................................................
Make statements on senses editable
Also adds a scaffolding for adding senses, with
the actual adding being not available now.
Bug: T165570
Change-Id: I6e07f1e658b20fc2a0b220429c4a5306dd1f14c4
---
M extension.json
M resources/jquery.wikibase.lexemeview.js
A resources/jquery.wikibase.senselistview.js
A resources/jquery.wikibase.senseview.js
M resources/lexeme.css
M resources/view/ControllerViewFactory.js
M src/WikibaseLexeme.hooks.php
A tests/qunit/jquery.wikibase.senselistview.tests.js
A tests/qunit/jquery.wikibase.senseview.tests.js
9 files changed, 343 insertions(+), 5 deletions(-)
Approvals:
Jonas Kress (WMDE): Looks good to me, but someone else must approve
Aleksey Bekh-Ivanov (WMDE): Looks good to me, approved
jenkins-bot: Verified
diff --git a/extension.json b/extension.json
index 5a709bb..b47500b 100644
--- a/extension.json
+++ b/extension.json
@@ -51,6 +51,7 @@
"dependencies": [
"jquery.wikibase.entityview",
"jquery.wikibase.lexemeformlistview",
+ "jquery.wikibase.senselistview",
"wikibase.lexeme.view.ControllerViewFactory",
"lemma-widget",
"wikibase.lexeme.widgets.GlossWidget"
@@ -92,6 +93,23 @@
"jquery.ui.EditableTemplatedWidget",
"wikibase.templates.lexeme",
"wikibase.lexeme.widgets.GrammaticalFeatureListWidget"
+ ]
+ },
+ "jquery.wikibase.senselistview": {
+ "scripts": "jquery.wikibase.senselistview.js",
+ "dependencies": [
+ "jquery.ui.widget",
+ "jquery.wikibase.senseview"
+ ]
+ },
+ "jquery.wikibase.senseview": {
+ "scripts": "jquery.wikibase.senseview.js",
+ "dependencies": [
+ "jquery.ui.widget",
+ "wikibase.templates.lexeme"
+ ],
+ "messages": [
+ "wikibase-statementsection-statements"
]
},
"vue": {
@@ -292,6 +310,7 @@
"util.inherit",
"wikibase.lexeme",
"wikibase.lexeme.datamodel.LexemeForm",
+ "wikibase.lexeme.datamodel.Sense",
"wikibase.view.ControllerViewFactory"
]
},
diff --git a/resources/jquery.wikibase.lexemeview.js
b/resources/jquery.wikibase.lexemeview.js
index 52775dd..f568038 100644
--- a/resources/jquery.wikibase.lexemeview.js
+++ b/resources/jquery.wikibase.lexemeview.js
@@ -16,6 +16,7 @@
* @param {Object} options
* @param {Function} options.buildStatementGroupListView
* @param {Function} options.buildLexemeFormListView
+ * @param {Function} options.buildSenseListView
*
* @constructor
*
@@ -27,7 +28,8 @@
*/
options: {
buildStatementGroupListView: null,
- buildLexemeFormListView: null
+ buildLexemeFormListView: null,
+ buildSenseListView: null
},
/**
@@ -49,6 +51,7 @@
}
this.options.buildLexemeFormListView();
+ this.options.buildSenseListView();
GlossWidget.applyWidgetToLexemePage();
},
@@ -57,7 +60,10 @@
* @protected
*/
_init: function () {
- if ( !this.options.buildStatementGroupListView ||
!this.options.buildLexemeFormListView ) {
+ if ( !this.options.buildStatementGroupListView ||
+ !this.options.buildLexemeFormListView ||
+ !this.options.buildSenseListView
+ ) {
throw new Error( 'Required option(s) missing' );
}
diff --git a/resources/jquery.wikibase.senselistview.js
b/resources/jquery.wikibase.senselistview.js
new file mode 100644
index 0000000..9236d22
--- /dev/null
+++ b/resources/jquery.wikibase.senselistview.js
@@ -0,0 +1,64 @@
+( function ( $ ) {
+ 'use strict';
+
+ var PARENT = $.Widget;
+
+ /**
+ * @class jQuery.wikibase.senselistview
+ * @extends jQuery.ui.Widget
+ * @license GPL-2.0+
+ *
+ * @constructor
+ *
+ * @param {Object} options
+ * @param {jquery.wikibase.listview.ListItemAdapter}
options.getListItemAdapter
+ * @param {jQuery.wikibase.addtoolbar} options.getAdder
+ * @param {wikibase.lexeme.datamodel.Sense} options.value
+ */
+ $.widget( 'wikibase.senselistview', PARENT, {
+ /**
+ * @inheritdoc
+ */
+ options: {
+ getListItemAdapter: null,
+ value: null
+ },
+
+ /**
+ * @type {jQuery.wikibase.listview}
+ * @private
+ */
+ _listview: null,
+
+ /**
+ * @inheritdoc
+ */
+ _create: function () {
+ PARENT.prototype._create.call( this );
+
+ this._createListView();
+ },
+
+ /**
+ * @inheritdoc
+ */
+ destroy: function () {
+ this._listview.destroy();
+ PARENT.prototype.destroy.call( this );
+ },
+
+ /**
+ * Creates the `listview` widget managing the `senseview`
widgets.
+ *
+ * @private
+ */
+ _createListView: function () {
+ this._listview = new $.wikibase.listview( {
+ listItemAdapter:
this.options.getListItemAdapter(),
+ listItemNodeName: 'div',
+ value: this.options.value
+ }, this.element.find( '.wikibase-lexeme-senses' ) );
+ }
+
+ } );
+}( jQuery ) );
diff --git a/resources/jquery.wikibase.senseview.js
b/resources/jquery.wikibase.senseview.js
new file mode 100644
index 0000000..851780f
--- /dev/null
+++ b/resources/jquery.wikibase.senseview.js
@@ -0,0 +1,59 @@
+( function ( $, mw ) {
+ 'use strict';
+
+ var PARENT = $.Widget;
+
+ /**
+ * Initializes StatementGroupListView on given DOM element
+ * @callback buildStatementGroupListView
+ * @param {wikibase.lexeme.datamodel.Sense}
+ * @param {jQuery} JQuery DOM element
+ */
+
+ /**
+ * @class jQuery.wikibase.senseview
+ * @extends jQuery.ui.Widget
+ * @license GPL-2.0+
+ *
+ * @constructor
+ *
+ * @param {Object} options
+ */
+ $.widget( 'wikibase.senseview', PARENT, {
+ options: {
+ /**
+ * @type {buildStatementGroupListView}
+ */
+ buildStatementGroupListView: null
+ },
+
+ /**
+ * This method acts as a setter if it is given a Sense object.
+ * Otherwise it returns its value.
+ *
+ * @param {wikibase.lexeme.datamodel.Sense} sense
+ * @return {wikibase.lexeme.datamodel.Sense|undefined}
+ */
+ value: function ( sense ) {
+ if ( sense instanceof wikibase.lexeme.datamodel.Sense )
{
+ this.option( 'value', sense );
+ return;
+ }
+
+ return this.options.value;
+ },
+
+ _create: function () {
+ PARENT.prototype._create.call( this );
+
+ this.options.buildStatementGroupListView(
+ this.value(),
+ $( '.wikibase-statementgrouplistview',
this.element )
+ );
+ },
+
+ getHelpMessage: function () {
+ return $.Deferred().resolve( this.options.helpMessage
).promise();
+ }
+ } );
+}( jQuery, mediaWiki ) );
diff --git a/resources/lexeme.css b/resources/lexeme.css
index 18fda18..372daf7 100644
--- a/resources/lexeme.css
+++ b/resources/lexeme.css
@@ -243,3 +243,15 @@
.wikibase-lexeme-sense-glosses-control:hover {
text-decoration: underline;
}
+
+.wikibase-lexeme-sense .wikibase-statementgrouplistview::after {
+ /* This is clearfix */
+ /* TODO: Should be done in Wikibase for all elements */
+ content: "";
+ display: table;
+ clear: both;
+}
+
+.wikibase-lexeme-sense > .wikibase-edittoolbar-container {
+ display: none; /* FIXME: temporarily hidden until entering/editing
glosses is possible */
+}
\ No newline at end of file
diff --git a/resources/view/ControllerViewFactory.js
b/resources/view/ControllerViewFactory.js
index 35e5911..8905c8d 100644
--- a/resources/view/ControllerViewFactory.js
+++ b/resources/view/ControllerViewFactory.js
@@ -34,7 +34,7 @@
$.extend( fakeStatementsChanger,
statementsChanger );
fakeStatementsChanger.save = function
fakeStatementsChangerSave( statement ) {
var guid =
statement.getClaim().getGuid();
- if ( /^L\d+-F\d+/.test( guid ) ||
/^F\d+/.test( guid ) ) {
+ if ( /^L\d+-[FS]\d+/.test( guid ) ||
/^[FS]\d+/.test( guid ) ) {
return $.Deferred().resolve(
statement ).promise();
} else {
return statementsChanger.save(
statement );
@@ -74,6 +74,7 @@
buildSitelinkGroupListView:
this.getSitelinkGroupListView.bind( this, startEditingCallback ),
buildStatementGroupListView:
this.getStatementGroupListView.bind( this, startEditingCallback ),
buildLexemeFormListView:
this.getLexemeFormListView.bind( this, lexeme, startEditingCallback ),
+ buildSenseListView: this.getSenseListView.bind(
this, lexeme, startEditingCallback ),
value: lexeme
}
);
@@ -91,6 +92,17 @@
getListItemAdapter:
this.getListItemAdapterForLexemeFormListView.bind( this, lexeme,
startEditingCallback ),
getAdder: this._getAdderWithStartEditing(
startEditingCallback ),
value: lexeme.forms
+ }
+ );
+ };
+
+ SELF.prototype.getSenseListView = function ( lexeme,
startEditingCallback ) {
+ return this._getView(
+ 'senselistview',
+ $( '.wikibase-lexeme-senses-section' ),
+ {
+ getListItemAdapter:
this.getListItemAdapterForSenseListView.bind( this, lexeme,
startEditingCallback, function () {} ),
+ value: lexeme.senses
}
);
};
@@ -132,7 +144,7 @@
controller = this._getController(
this._toolbarFactory.getToolbarContainer(
lexemeFormView.element ),
lexemeFormView,
- fakeModelCreator( lexemeId ),
+ fakeFormModelCreator( lexemeId ),
removeCallback.bind( null, lexemeFormView ),
form,
startEditingCallback
@@ -146,7 +158,7 @@
return lexemeFormView;
};
- function fakeModelCreator( lexemeId ) {
+ function fakeFormModelCreator( lexemeId ) {
return { // FIXME: replace with EntityChanger
save: function ( form ) {
var deferred = $.Deferred();
@@ -154,6 +166,51 @@
form._id = lexemeId + '-F' +
Math.round( Math.random() * 100 );
}
deferred.resolve( form );
+ return deferred.promise();
+ }
+ };
+ }
+
+ SELF.prototype.getSenseView = function (
+ lexemeId,
+ sense,
+ $dom,
+ startEditingCallback,
+ removeCallback
+ ) {
+ var self = this;
+
+ var senseView = this._getView(
+ 'senseview',
+ $dom,
+ {
+ value: sense || new wb.lexeme.datamodel.Sense(),
+ buildStatementGroupListView:
this.getStatementGroupListView.bind(
+ this,
+ startEditingCallback
+ )
+ }
+ ),
+ controller = this._getController(
+ this._toolbarFactory.getToolbarContainer(
senseView.element ),
+ senseView,
+ fakeSenseModelCreator( lexemeId ),
+ removeCallback.bind( null, senseView ),
+ sense,
+ startEditingCallback
+ );
+
+ return senseView;
+ };
+
+ function fakeSenseModelCreator( lexemeId ) {
+ return { // FIXME: replace with EntityChanger
+ save: function ( sense ) {
+ var deferred = $.Deferred();
+ if ( !sense.getId() ) {
+ sense._id = lexemeId + '-S' +
Math.round( Math.random() * 100 );
+ }
+ deferred.resolve( sense );
return deferred.promise();
}
};
@@ -241,6 +298,25 @@
return existingGrammaticalFeatures.concat(
deletedGrammaticalFeatures );
};
+ SELF.prototype.getListItemAdapterForSenseListView = function ( lexeme,
startEditingCallback, removeCallback ) {
+ var self = this;
+
+ return new $.wikibase.listview.ListItemAdapter( {
+ listItemWidget: $.wikibase.senseview,
+ getNewItem: function ( sense, element ) {
+ var $element = $( element );
+
+ return self.getSenseView(
+ lexeme.getId(),
+ sense || null,
+ $element,
+ startEditingCallback,
+ removeCallback
+ );
+ }
+ } );
+ };
+
wb.lexeme.view.ControllerViewFactory = SELF;
}( mediaWiki, wikibase, jQuery ) );
diff --git a/src/WikibaseLexeme.hooks.php b/src/WikibaseLexeme.hooks.php
index 902b9d7..17d70c0 100644
--- a/src/WikibaseLexeme.hooks.php
+++ b/src/WikibaseLexeme.hooks.php
@@ -100,6 +100,8 @@
'tests/qunit/jquery.wikibase.lexemeformlistview.tests.js',
'tests/qunit/jquery.wikibase.lexemeformview.tests.js',
'tests/qunit/jquery.wikibase.grammaticalfeatureview.tests.js',
+
'tests/qunit/jquery.wikibase.senselistview.tests.js',
+
'tests/qunit/jquery.wikibase.senseview.tests.js',
'tests/qunit/serialization/LexemeDeserializer.tests.js',
'tests/qunit/services/ItemLookup.tests.js',
'tests/qunit/services/LanguageFromItemExtractor.tests.js',
@@ -114,6 +116,8 @@
'jquery.wikibase.lexemeformlistview',
'jquery.wikibase.lexemeformview',
'jquery.wikibase.grammaticalfeatureview',
+ 'jquery.wikibase.senselistview',
+ 'jquery.wikibase.senseview',
'oojs-ui',
'wikibase.lexeme.datamodel.LexemeForm',
'wikibase.lexeme.datamodel.Sense',
diff --git a/tests/qunit/jquery.wikibase.senselistview.tests.js
b/tests/qunit/jquery.wikibase.senselistview.tests.js
new file mode 100644
index 0000000..bf9aa43
--- /dev/null
+++ b/tests/qunit/jquery.wikibase.senselistview.tests.js
@@ -0,0 +1,48 @@
+/**
+ * @license GPL-2.0+
+ */
+( function ( $, wb, QUnit, sinon ) {
+ 'use strict';
+
+ var senseviewListItemAdapter = wb.tests.getMockListItemAdapter(
+ 'senseview',
+ function () {
+ }
+ );
+
+ var createViewElement = function () {
+ var $node = $( '<div><div
class="wikibase-lexeme-senses"/></div>' );
+ return $node.senselistview( {
+ getListItemAdapter: function () {
+ return senseviewListItemAdapter;
+ }
+ } );
+ };
+
+ var getViewFromElement = function ( $view ) {
+ return $view.data( 'senselistview' );
+ };
+
+ var newView = function () {
+ return getViewFromElement( createViewElement() );
+ };
+
+ QUnit.module( 'jquery.wikibase.senselistview' );
+
+ QUnit.test( 'Can be created', function ( assert ) {
+ var view = newView();
+
+ assert.ok( view instanceof $.wikibase.senselistview );
+ } );
+
+ QUnit.test( 'Can be destroyed', function ( assert ) {
+ var $view = createViewElement();
+
+ assert.ok( getViewFromElement( $view ) );
+
+ $view.data( 'senselistview' ).destroy();
+
+ assert.notOk( getViewFromElement( $view ) );
+ } );
+
+}( jQuery, wikibase, QUnit, sinon ) );
diff --git a/tests/qunit/jquery.wikibase.senseview.tests.js
b/tests/qunit/jquery.wikibase.senseview.tests.js
new file mode 100644
index 0000000..f5d4579
--- /dev/null
+++ b/tests/qunit/jquery.wikibase.senseview.tests.js
@@ -0,0 +1,50 @@
+/**
+ * @license GPL-2.0+
+ */
+( function ( $, wb, QUnit ) {
+ 'use strict';
+
+ var TEST_LEXMEFORMVIEW_CLASS = 'test_senseview';
+
+ QUnit.module( 'jquery.wikibase.senseview', QUnit.newMwEnvironment( {
+ teardown: function () {
+ $( '.' + TEST_LEXMEFORMVIEW_CLASS ).remove();
+ }
+ } ) );
+
+ var newSenseView = function ( options ) {
+ var $node = $( '<div/>' ).appendTo( 'body' );
+ options = options || {};
+
+ $node.addClass( TEST_LEXMEFORMVIEW_CLASS );
+
+ options.buildStatementGroupListView = function () {};
+
+ return $node.senseview( options || {} ).data( 'senseview' );
+ };
+
+ var newSense = function ( id, enGloss ) {
+ return new wb.lexeme.datamodel.Sense( id, { en: enGloss } );
+ };
+
+ QUnit.test( 'can be created', function ( assert ) {
+ assert.ok( newSenseView() instanceof $.wikibase.senseview );
+ } );
+
+ QUnit.test( 'value can be injected as option.value', function ( assert
) {
+ var sense = newSense( 'S123', 'foo' ),
+ view = newSenseView( { value: sense } );
+
+ assert.equal( view.value(), sense );
+ } );
+
+ QUnit.test( 'value() sets internal value', function ( assert ) {
+ var sense1 = newSense( 'S123', 'foo' ),
+ sense2 = newSense( 'S234', 'bar' ),
+ view = newSenseView( { value: sense2 } );
+
+ view.value( sense2 );
+ assert.equal( view.value(), sense2 );
+ } );
+
+}( jQuery, wikibase, QUnit ) );
--
To view, visit https://gerrit.wikimedia.org/r/359471
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I6e07f1e658b20fc2a0b220429c4a5306dd1f14c4
Gerrit-PatchSet: 12
Gerrit-Project: mediawiki/extensions/WikibaseLexeme
Gerrit-Branch: master
Gerrit-Owner: WMDE-leszek <[email protected]>
Gerrit-Reviewer: Aleksey Bekh-Ivanov (WMDE) <[email protected]>
Gerrit-Reviewer: Jakob <[email protected]>
Gerrit-Reviewer: Jonas Kress (WMDE) <[email protected]>
Gerrit-Reviewer: Thiemo Mättig (WMDE) <[email protected]>
Gerrit-Reviewer: WMDE-leszek <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits