Henning Snater has uploaded a new change for review.
https://gerrit.wikimedia.org/r/189018
Change subject: snakview: Refactored drawing mechanism
......................................................................
snakview: Refactored drawing mechanism
- untangled draw() / drawProperty() relationship moving Property specific logic
out of draw()
- drawProperty() does not (re)render when previously generated HTML is detected
- Property and Snak type are not (re)rendered when they are locked and there
previously generated
HTML is detected.
- Made updateVariation() public. There is no sense in being able to (re)draw
the Variation without
being able to update it.
- Removed parameter from updateVariation() as it is supposed to always reflect
the current value.
- Removed parameter from drawProperty as it is supposed to always reflect the
current value.
- 88425
Change-Id: If45c707c08ba710fe5fec456fef29c2b60586dae
---
M lib/resources/jquery.wikibase/snakview/snakview.js
M lib/resources/jquery.wikibase/snakview/snakview.variations.Value.js
2 files changed, 112 insertions(+), 61 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Wikibase
refs/changes/18/189018/1
diff --git a/lib/resources/jquery.wikibase/snakview/snakview.js
b/lib/resources/jquery.wikibase/snakview/snakview.js
index 1eb5eb9..2d7fecc 100644
--- a/lib/resources/jquery.wikibase/snakview/snakview.js
+++ b/lib/resources/jquery.wikibase/snakview/snakview.js
@@ -162,7 +162,8 @@
this._cachedValues = {};
- this.value( this.options.value );
+ this.updateVariation();
+ this.draw();
if( this.option( 'autoStartEditing' ) && !this.snak() ) {
// If no Snak is represented, offer UI to build one.
@@ -197,10 +198,7 @@
var response = PARENT.prototype._setOption.apply( this,
arguments );
if( key === 'value' ) {
- value = this.value();
-
- this._updateVariation( value );
-
+ this.updateVariation();
this.draw();
} else if( key === 'disabled' ) {
var propertySelector = this._getPropertySelector(),
@@ -253,7 +251,7 @@
// remove out-dated variations
if( self._variation ) {
self.drawSnakTypeSelector();
- self._updateVariation( self.value() );
+ self.updateVariation();
self.drawVariation();
self._trigger( 'change' );
}
@@ -265,7 +263,7 @@
);
self.options.entityStore.get( entityId ).done(
function( entity ) {
- self._updateVariation( self.value() );
+ self.updateVariation();
self.drawSnakTypeSelector();
self.drawVariation();
@@ -640,18 +638,15 @@
},
/**
- * Checks whether the `Snak` type has been changed by the user and will
build a new `Variation`
- * object for that type if necessary.
- * @private
- * @since 0.4
- *
- * @param {Object} value (In)complete `Snak` serialization.
+ * Updates the `Variation` according to the widget's current value.
+ * @since 0.5
*/
- _updateVariation: function( value ) {
- var variationsFactory = $.wikibase.snakview.variations,
+ updateVariation: function() {
+ var value = this.value(),
+ propertyId = value ? value.property : null,
snakType = value ? value.snaktype : null,
- VariationConstructor = snakType ?
variationsFactory.getVariation( snakType ) : null,
- propertyId = value ? value.property : null;
+ variationsFactory = $.wikibase.snakview.variations,
+ VariationConstructor = snakType ?
variationsFactory.getVariation( snakType ) : null;
if( this._variation
&& ( !propertyId || this._variation.constructor !==
VariationConstructor )
@@ -701,82 +696,134 @@
},
/**
- * Renders the `snakview`'s current state considering edit mode,
current value, etc..
+ * (Re)renders the widget.
* @since 0.4
*/
draw: function() {
- var self = this,
- value = this.value(),
- propertyId = value ? value.property : null;
-
- // NOTE: Order of these shouldn't matter; If for any reasons
draw functions start changing
- // the outcome of the variation (or Snak type), then something
must be incredibly wrong!
- if( propertyId ) {
- this.options.entityStore.get( propertyId ).done(
function( fetchedProperty ) {
- self.drawProperty(
- fetchedProperty ?
fetchedProperty.getContent() : null,
- fetchedProperty ?
fetchedProperty.getTitle() : null
- );
- } );
- } else {
- this.drawProperty( null, null );
- }
+ this.drawProperty();
this.drawSnakTypeSelector();
this.drawVariation();
},
/**
- * Ensures the current `Snak`'s `Property` is displayed properly. If no
`Snak` is set, the input
- * form for specifying the `Snak`'s `Property` will be rendered.
- * @since 0.4
+ * (Re)renders the Property DOM structure according to the current
value. The `Property` DOM
+ * is not (re-)rendered if changing the `Property` is locked via the
`locked` option and
+ * previously generated HTML is detected.
+ * @since 0.5
*
- * @param {wikibase.datamodel.Property|null} property
- * @param {mediawiki.Title|null} title Only supposed to be `null` if
`property` is `null`.
+ * @return {Object} jQuery.Promise
+ * @return {Function} return.done
+ * @return {Function} return.fail
*/
- drawProperty: function( property, title ) {
- var $propertyDom,
- value = this.value(),
- propertyId = value ? value.property : null;
+ drawProperty: function() {
+ var self = this,
+ deferred = $.Deferred(),
+ propertyId = this.value().property;
+
+ if( this.options.locked.property &&
this.$property.contents().length ) {
+ return deferred.resolve().promise();
+ }
+
+ this._getPropertyDOM( propertyId )
+ .done( function( $property ) {
+ self.$property.empty().append( $property );
+ deferred.resolve();
+ } )
+ .fail( function() {
+ self.$property.empty().text( propertyId );
+ deferred.reject();
+ } );
+
+ return deferred.promise();
+ },
+
+ /**
+ * Retrieves the DOM structure representing the `Property` of the
`Snak` represented by the
+ * `snakview`.
+ * @private
+ *
+ * @param {string} [propertyId]
+ * @return {Object} jQuery.Promise
+ * @return {Function} return.done
+ * @return {jQuery} return.$property
+ * @return {Function} return.fail
+ */
+ _getPropertyDOM: function( propertyId ) {
+ var self = this,
+ deferred = $.Deferred();
+
+ if( propertyId ) {
+ this.options.entityStore.get( propertyId )
+ .done( function( fetchedProperty ) {
+ deferred.resolve( self._createPropertyDOM(
+ fetchedProperty ?
fetchedProperty.getContent() : undefined,
+ fetchedProperty ?
fetchedProperty.getTitle() : undefined
+ ) );
+ } )
+ .fail( deferred.reject );
+ } else {
+ deferred.resolve( this._createPropertyDOM() );
+ }
+
+ return deferred.promise();
+ },
+
+ /**
+ * Creates the DOM structure specific for a `Property`-`Title`
combination, a generic DOM
+ * structure or an input element if parameters are omitted.
+ * @private
+ *
+ * @param {wikibase.datamodel.Property|string} [property] `Property`
object or `Property` id.
+ * Returns generic DOM structure if omitted.
+ * @param {mediawiki.Title} [title]
+ * @return {jQuery}
+ */
+ _createPropertyDOM: function( property, title ) {
+ var $propertyDom;
if( this.options.locked.property || !this.isInEditMode() ) {
- // property set and can't be changed afterwards, only
display label
- $propertyDom = property
+ // Property is set already and cannot be changed,
display label only:
+ $propertyDom = property instanceof wb.datamodel.Property
? wb.utilities.ui.buildLinkToEntityPage(
property, title )
// shouldn't usually happen, only in non-edit
mode, while no Snak is set:
- : wb.utilities.ui.buildMissingEntityInfo(
propertyId, wb.datamodel.Property );
+ : wb.utilities.ui.buildMissingEntityInfo(
property, wb.datamodel.Property );
} else {
- // no property set for this Snak, serve edit view to
specify it:
+ // No Property set for this Snak, serve edit view to
specify it:
var propertySelector = this._getPropertySelector(),
- propertyLabel =
wb.utilities.ui.buildPrettyEntityLabelText( property );
+ propertyLabel = property instanceof
wb.datamodel.Property
+ ?
wb.utilities.ui.buildPrettyEntityLabelText( property )
+ : property;
// TODO: use selectedEntity() or other command to set
selected entity in both cases!
- if( propertySelector && property ) {
+ if( propertySelector ) {
// property selector in DOM already, just
replace current value
var currentValue =
propertySelector.widget().val();
// Impose case-insensitivity:
if( propertyLabel.toLowerCase() !==
currentValue.toLocaleLowerCase() ) {
propertySelector.widget().val(
propertyLabel );
}
- return;
- } else if( !propertySelector ) {
- // Create property selector and set value:
+ } else {
$propertyDom =
this._buildPropertySelector().val( propertyLabel );
// propagate snakview state:
$propertyDom.data( 'entityselector' ).option(
'disabled', this.options.disabled );
- } else {
- return;
}
}
- this.$property.empty().append( $propertyDom );
+ return $propertyDom;
},
/**
- * Updates the `snaktypeselector` for choosing the `Snak` type.
+ * Updates the `SnakTypeSelector` for choosing the `Snak` type. The
`SnakTypeSelector` DOM
+ * is not (re-)rendered if changing the `Snak` type is locked via the
`locked` option and
+ * previously generated HTML is detected.
* @since 0.4
*/
drawSnakTypeSelector: function() {
+ if( this.options.locked.snaktype &&
this.$snakTypeSelector.contents().length ) {
+ return;
+ }
+
var snakTypes =
$.wikibase.snakview.variations.getCoveredSnakTypes(),
selector = this._getSnakTypeSelector();
@@ -846,7 +893,7 @@
// NOTE: instead of doing this here and
checking everywhere whether this._variation
// is set, we could as well use variations for
displaying system messages like
// this, e.g. having a UnsupportedSnakType
variation which is not registered for a
- // specific snak type but is known to
_updateVariation().
+ // specific snak type but is known to
updateVariation().
}
}
},
@@ -871,7 +918,7 @@
// bind user interaction on selector to snakview's state:
$anchor.on( changeEvent + '.' + this.widgetName, function(
event ) {
- self._updateVariation( self.value() );
+ self.updateVariation();
self.drawVariation();
if( self._variation ) {
self._variation.focus();
diff --git
a/lib/resources/jquery.wikibase/snakview/snakview.variations.Value.js
b/lib/resources/jquery.wikibase/snakview/snakview.variations.Value.js
index ceaff79..c1fe35a 100644
--- a/lib/resources/jquery.wikibase/snakview/snakview.variations.Value.js
+++ b/lib/resources/jquery.wikibase/snakview/snakview.variations.Value.js
@@ -20,7 +20,7 @@
MODULE.variation( wb.datamodel.PropertyValueSnak, PARENT, {
/**
* The value view widget object or null if property's data type
isn't supported.
- * @type jQuery.valueview.Widget
+ * @type {jQuery.valueview|null}
*/
_valueView: null,
@@ -356,14 +356,18 @@
* @inheritdoc
*/
disable: function() {
- this._valueView.disable();
+ if( this._valueView ) {
+ this._valueView.disable();
+ }
},
/**
* @inheritdoc
*/
enable: function() {
- this._valueView.enable();
+ if( this._valueView ) {
+ this._valueView.enable();
+ }
},
/*
--
To view, visit https://gerrit.wikimedia.org/r/189018
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: If45c707c08ba710fe5fec456fef29c2b60586dae
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Henning Snater <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits