Tobias Gritschacher has submitted this change and it was merged. Change subject: (bug 44683) Implementing qualifiers in the JavaScript UI ......................................................................
(bug 44683) Implementing qualifiers in the JavaScript UI Qualifiers may be added to existing claims/statements now via the JavaScript user interface. The change set extends the claim and statement templates and adds two addition toolbar definitions (add and remove qualifier snak) to the claimview widget. - patch set 8: Minor code improvement Change-Id: I236bdd0a7e9c8004a4b1a3c2eff83d690985cd05 --- M lib/resources/Resources.php M lib/resources/jquery.wikibase/jquery.wikibase.claimview.js M lib/resources/jquery.wikibase/jquery.wikibase.entityview.js M lib/resources/jquery.wikibase/jquery.wikibase.referenceview.js M lib/resources/jquery.wikibase/jquery.wikibase.snaklistview.js M lib/resources/jquery.wikibase/jquery.wikibase.statementview.js M lib/resources/jquery.wikibase/jquery.wikibase.toolbarcontroller/toolbarcontroller.definitions.js M lib/resources/jquery.wikibase/jquery.wikibase.toolbarcontroller/toolbarcontroller.js M lib/resources/templates.php M lib/resources/wikibase.css M repo/Wikibase.i18n.php M repo/includes/EntityView.php M repo/resources/wikibase.ui.entityViewInit.js 13 files changed, 343 insertions(+), 95 deletions(-) Approvals: Tobias Gritschacher: Verified; Looks good to me, approved jenkins-bot: Checked diff --git a/lib/resources/Resources.php b/lib/resources/Resources.php index c6a45e5..49ed5f1 100644 --- a/lib/resources/Resources.php +++ b/lib/resources/Resources.php @@ -554,6 +554,7 @@ 'jquery.wikibase.snakview' ), 'messages' => array( + 'wikibase-addqualifier', 'wikibase-claimview-snak-tooltip', 'wikibase-claimview-snak-new-tooltip' ) diff --git a/lib/resources/jquery.wikibase/jquery.wikibase.claimview.js b/lib/resources/jquery.wikibase/jquery.wikibase.claimview.js index 5a4f93c..4037049 100644 --- a/lib/resources/jquery.wikibase/jquery.wikibase.claimview.js +++ b/lib/resources/jquery.wikibase/jquery.wikibase.claimview.js @@ -74,10 +74,12 @@ return ( this._claim && this._claim.getGuid() ) || 'new'; }, 'wb-last', // class: wb-first|wb-last - '' // .wb-claim-mainsnak + '', // .wb-claim-mainsnak + '' // Qualifiers ], templateShortCuts: { - '$mainSnak': '.wb-claim-mainsnak' + '$mainSnak': '.wb-claim-mainsnak', + '$qualifiers': '.wb-statement-qualifiers' }, value: null, predefined: { @@ -108,16 +110,17 @@ _claim: null, /** + * Reference to the listview widget managing the qualifier snaks. Basically, just a short-cut + * for this.$qualifiers.data( 'listview' ) + * @type {jquery.wikibase.listview} + */ + _qualifiers: null, + + /** * Whether the Claim is currently in edit mode. * @type {boolean} */ _isInEditMode: false, - - /** - * Whether the widget is currently valid according to its contents. - * @type {boolean} - */ - _isValid: false, /** * @see jQuery.Widget._create @@ -132,23 +135,19 @@ // set up event listeners: this.$mainSnak .on ( 'snakviewchange', function( event, status ) { - var snakview = self.$mainSnak.data( 'snakview' ); - self._isValid = ( snakview.isValid() && !snakview.isInitialSnak() ); self._trigger( 'change' ); } ) .on( 'snakviewstopediting', function( event, dropValue ) { // React on key stroke events (e.g. pressing enter or ESC key) - if ( !self.isValid() && !dropValue ) { + if ( + ( !self.isValid() || self.isInitialValue() ) + && !dropValue && !self.__continueStopEditing + ) { event.preventDefault(); - return; - } - - if ( !self.__continueStopEditing ) { + } else if ( !self.__continueStopEditing ) { // Do not exit snakview's edit mode yet; Let any API request be performed first. event.preventDefault(); self.stopEditing( dropValue ); - } else { - self.__continueStopEditing = false; } } ) .on( 'valueviewchange', function( e ) { @@ -162,6 +161,34 @@ locked: this.option( 'locked' ).mainSnak, autoStartEditing: false // manually, after toolbar is there, so events can access toolbar } ); + + // Initialize qualifiers: + // TODO: Allow adding qualifiers when adding a new claim. + if ( this.option( 'value' ) ) { + var $qualifiers = $( '<div/>' ) + .prependTo( this.$qualifiers ) + .snaklistview( { + value: ( this._claim ) ? this._claim.getQualifiers() : null + } ) + .on( 'snaklistviewchange', function( event ) { + self._trigger( 'change' ); + } ) + .on( 'snaklistviewstopediting', function( event, dropValue ) { + // React on key stroke events (e.g. pressing enter or ESC key) + if ( + ( !self.isValid() || self.isInitialValue() ) + && !dropValue && !self.__continueStopEditing + ) { + event.preventDefault(); + } else if ( !self.__continueStopEditing ) { + // Do not exit snakview's edit mode yet; Let any API request be performed first. + event.preventDefault(); + self.stopEditing( dropValue ); + } + } ); + + this._qualifiers = $qualifiers.data( 'snaklistview' ); + } if ( this._claim || this.options.predefined.mainSnak ) { var property = this._claim @@ -178,11 +205,27 @@ /** * Returns whether the claimview is valid according to its current contents. + * @since 0.4 * * @return {boolean} */ isValid: function() { - return this._isValid; + var snakview = this.$mainSnak.data( 'snakview' ); + return ( snakview.isValid() && ( !this._qualifiers || this._qualifiers.isValid() ) ); + }, + + /** + * Returns whether the current value of this claim (including the qualifiers) equals the value + * the claim has been initialized with. + * @since 0.4 + * + * @returns {boolean} + */ + isInitialValue: function() { + return ( + this.$mainSnak.data( 'snakview' ).isInitialSnak() + && ( !this._qualifiers || this._qualifiers.isInitialValue() ) + ); }, /** @@ -204,10 +247,12 @@ this.$mainSnak.data( 'snakview' ).startEditing(); + if ( this._qualifiers ) { + this._qualifiers.startEditing(); + } + this.element.addClass( 'wb-edit' ); this._isInEditMode = true; - - this._isValid = ( snakview.isValid() && !snakview.isInitialSnak() ); this._trigger( 'afterstartediting' ); } @@ -225,11 +270,11 @@ stopEditing: $.NativeEventHandler( 'stopEditing', { // don't stop edit mode or trigger event if not in edit mode currently: initially: function( e, dropValue ) { - if( !this.isInEditMode() || !this.isValid() && !dropValue ) { + if ( + !this.isInEditMode() || ( !this.isValid() || this.isInitialValue() ) && !dropValue + ) { e.cancel(); } - - this.__continueStopEditing = true; this.element.removeClass( 'wb-error' ); }, @@ -241,20 +286,37 @@ if ( dropValue ) { // nothing to update + this.__continueStopEditing = true; + if ( this.$mainSnak.data( 'snakview' ) ) { this.$mainSnak.data( 'snakview' ).stopEditing( dropValue ); } + + if ( this._qualifiers ) { + this._qualifiers.stopEditing( dropValue ); + } + + this.__continueStopEditing = false; self.enable(); self.element.removeClass( 'wb-edit' ); self._isInEditMode = false; self._trigger( 'afterstopediting', null, [ dropValue ] ); - } else if ( this._claim ) { + } else if ( this._claim && !this.__continueStopEditing ) { // editing an existing claim self._saveClaimApiCall() .done( function( savedClaim, pageInfo ) { + self.__continueStopEditing = true; + self.$mainSnak.data( 'snakview' ).stopEditing( dropValue ); + + if ( self._qualifiers ) { + self._qualifiers.__continueStopEditing = true; + self._qualifiers.stopEditing(); + } + + self.__continueStopEditing = false; self.enable(); @@ -283,7 +345,7 @@ self.__continueStopEditing = false; } ); - } else { + } else if ( !this.__continueStopEditing ) { // Adding a new claim is managed in claimlistview and will end up in here after // having performed the API call adding the claim. self.element.removeClass( 'wb-edit' ); @@ -363,8 +425,8 @@ revStore = wb.getRevisionStore(), guid = this.value().getGuid(), claim = new wb.Claim( - self.$mainSnak.data( 'snakview' ).snak(), - new wb.SnakList(), // TODO: Qualifiers + this.$mainSnak.data( 'snakview' ).snak(), + ( this._qualifiers ) ? this._qualifiers.value() : null, guid ); @@ -375,6 +437,7 @@ // Update model of represented Claim: self._claim = savedClaim; + self._qualifiers.value( savedClaim.getQualifiers() ); } ); }, @@ -465,4 +528,101 @@ } } ); +// Register toolbars: +$.wikibase.toolbarcontroller.definition( 'addtoolbar', { + id: 'claim-qualifiers-snak', + selector: '.wb-claim-qualifiers', + events: { + snaklistviewstartediting: 'create', + snaklistviewafterstopediting: 'destroy', + snaklistviewchange: function( event ) { + var snaklistview = $( event.target ).data( 'snaklistview' ), + addToolbar = $( event.target ).data( 'addtoolbar' ); + if ( addToolbar ) { + addToolbar.toolbar[snaklistview.isValid() ? 'enable' : 'disable'](); + } + }, + snaklistviewdisable: function( event ) { + $( event.target ).data( 'addtoolbar' ).toolbar.disable(); + }, + snaklistviewenable: function( event ) { + var addToolbar = $( event.target ).data( 'addtoolbar' ); + // "add" toolbar might be remove already. + if ( addToolbar ) { + addToolbar.toolbar.enable(); + } + }, + 'listviewitemadded listviewitemremoved': function( event ) { + // Enable "add" link when all qualifiers have been removed: + var $listviewNode = $( event.target ), + listview = $listviewNode.data( 'listview' ), + $snaklistviewNode = $listviewNode.closest( '.wb-snaklistview' ), + snaklistview = $snaklistviewNode.data( 'snaklistview' ), + addToolbar = $snaklistviewNode.data( 'addtoolbar' ); + + // Disable "add" toolbar when the last qualifier has been removed: + if ( !snaklistview.isValid() && listview.items().length ) { + addToolbar.toolbar.disable(); + } else { + addToolbar.toolbar.enable(); + } + } + }, + options: { + customAction: function( event, $parent ) { + $parent.data( 'snaklistview' ).enterNewItem(); + }, + eventPrefix: $.wikibase.snaklistview.prototype.widgetEventPrefix, + addButtonLabel: mw.msg( 'wikibase-addqualifier' ) + } +} ); + +$.wikibase.toolbarcontroller.definition( 'removetoolbar', { + id: 'claim-qualifiers-snak', + selector: '.wb-claim-qualifiers', + events: { + 'snakviewstartediting snakviewcreate listviewitemadded listviewitemremoved': function( event ) { + var $target = $( event.target ), + listview = $target.closest( '.wb-snaklistview' ).data( 'snaklistview' )._listview; + + if ( event.type.indexOf( 'snakview' ) !== -1 ) { + // Create toolbar for each snakview widget: + $target.removetoolbar( { + action: function( event ) { + listview.removeItem( $target ); + } + } ); + } + }, + snaklistviewafterstopediting: function( event ) { + // Destroy the snakview toolbars: + var $snaklistviewNode = $( event.target ), + listview = $snaklistviewNode.data( 'snaklistview' )._listview, + lia = listview.listItemAdapter(); + + $.each( listview.items(), function( i, item ) { + var snakview = lia.liInstance( $( item ) ); + if ( snakview.element.data( 'removetoolbar' ) ) { + snakview.element.data( 'removetoolbar' ).destroy(); + snakview.element.children( '.w-removetoolbar' ).remove(); + } + } ); + }, + 'snaklistviewdisable snaklistviewenable': function( event ) { + var $snaklistviewNode = $( event.target ), + listview = $snaklistviewNode.data( 'snaklistview' )._listview, + lia = listview.listItemAdapter(), + action = ( event.type.indexOf( 'disable' ) !== -1 ) ? 'disable' : 'enable'; + + $.each( listview.items(), function( i, item ) { + var $item = $( item ); + // Item might be about to be removed not being a list item instance. + if ( lia.liInstance( $item ) && $item.data( 'removetoolbar' ) ) { + $item.data( 'removetoolbar' ).toolbar[action](); + } + } ); + } + } +} ); + }( mediaWiki, wikibase, jQuery ) ); diff --git a/lib/resources/jquery.wikibase/jquery.wikibase.entityview.js b/lib/resources/jquery.wikibase/jquery.wikibase.entityview.js index b9d0a58..1b1ecc2 100644 --- a/lib/resources/jquery.wikibase/jquery.wikibase.entityview.js +++ b/lib/resources/jquery.wikibase/jquery.wikibase.entityview.js @@ -78,14 +78,16 @@ // there could be other ways for entering edit mode than using the toolbar! // Whether action shall influence sub-toolbars of origin: - var exclusive; - if ( options && typeof options.exclusive === 'boolean' ) { - exclusive = options.exclusive; + // TODO: "exclusive" option/variable restricts arrangement of toolbars. Interaction + // between toolbars should be managed via the toolbar controller. + var originToolbars = null; + if ( options ) { + if ( typeof options.exclusive === 'boolean' && !options.exclusive ) { + originToolbars = $( origin ).find( '.wb-ui-toolbar' ); + } else if ( $.isArray( options.exclusive ) !== -1 ) { + originToolbars = $( origin ).find( options.exclusive ); + } } - - var originToolbars = ( origin && exclusive === false ) - ? $( origin ).find( '.wb-ui-toolbar' ) - : null; // find and disable/enable all toolbars in this edit view except,... self.element.find( '.wb-ui-toolbar' ).each( function() { @@ -117,7 +119,13 @@ // TODO: this should rather listen to 'valueviewstartediting' once implemented! $( this.element ) .on( 'statementviewafterstartediting', function( event ) { - $( wb ).trigger( 'startItemPageEditMode', [ event.target, { exclusive: true } ] ); + $( wb ).trigger( 'startItemPageEditMode', [ + event.target, + { + exclusive: '.wb-claim-qualifiers .wb-ui-toolbar', + wbCopyrightWarningGravity: 'sw' + } + ] ); } ) .on( 'referenceviewafterstartediting', function( event ) { $( wb ).trigger( diff --git a/lib/resources/jquery.wikibase/jquery.wikibase.referenceview.js b/lib/resources/jquery.wikibase/jquery.wikibase.referenceview.js index a54df92..628a5a2 100644 --- a/lib/resources/jquery.wikibase/jquery.wikibase.referenceview.js +++ b/lib/resources/jquery.wikibase/jquery.wikibase.referenceview.js @@ -161,21 +161,20 @@ $.wikibase.toolbarcontroller.definition( 'addtoolbar', { id: 'referenceview-snakview', selector: '.wb-statement-references .wb-referenceview', - eventPrefix: 'referenceview', events: { - startediting: 'create', - afterstopediting: 'destroy', - change: function( event ) { + referenceviewstartediting: 'create', + referenceviewafterstopediting: 'destroy', + referenceviewchange: function( event ) { var referenceview = $( event.target ).data( 'referenceview' ), addToolbar = $( event.target ).data( 'addtoolbar' ); if ( addToolbar ) { addToolbar.toolbar[referenceview.isValid() ? 'enable' : 'disable'](); } }, - disable: function( event ) { + referenceviewdisable: function( event ) { $( event.target ).data( 'addtoolbar' ).toolbar.disable(); }, - enable: function( event ) { + referenceviewenable: function( event ) { var addToolbar = $( event.target ).data( 'addtoolbar' ); // "add" toolbar might be remove already. if ( addToolbar ) { diff --git a/lib/resources/jquery.wikibase/jquery.wikibase.snaklistview.js b/lib/resources/jquery.wikibase/jquery.wikibase.snaklistview.js index aaa665d..644c2e1 100644 --- a/lib/resources/jquery.wikibase/jquery.wikibase.snaklistview.js +++ b/lib/resources/jquery.wikibase/jquery.wikibase.snaklistview.js @@ -67,8 +67,7 @@ options: { template: 'wb-snaklistview', templateParams: [ - '', // listview widget - '' // edit section DOM + '' // listview widget ], templateShortCuts: { '$listview': '.wb-snaklistview-listview' @@ -157,7 +156,8 @@ this._lia = this._listview.listItemAdapter(); this.$listview - .on( 'listviewitemadded', function( event, value, $newLi ) { + .off( '.' + this.widgetName ) + .on( 'listviewitemadded.' + this.widgetName, function( event, value, $newLi ) { // Listen to all the snakview "change" events to be able to determine whether the // snaklistview itself is valid. $newLi.on( self._lia.prefixedEvent( 'change' ), function( event ) { @@ -165,20 +165,20 @@ self._trigger( 'change' ); } ); } ) - .on( self._lia.prefixedEvent( 'change' ) + ' listviewitemremoved', function( event ) { - // Forward the "change" event to external components (e.g. the edit toolbar). - self._trigger( 'change' ); - } ) - .on( self._lia.prefixedEvent( 'stopediting' ), + .on( self._lia.prefixedEvent( 'change.' ) + this.widgetName + + ' listviewitemremoved.' + this.widgetName, function( event ) { + // Forward the "change" event to external components (e.g. the edit toolbar). + self._trigger( 'change' ); + } + ) + .on( self._lia.prefixedEvent( 'stopediting.' + this.widgetName ), function( event, dropValue, newSnak ) { if ( - !self.isValid() && !self.isInitialValue() - && !dropValue && !self.__continueSnakviewStopEditing + ( !self.isValid() || self.isInitialValue() ) + && !dropValue && !self.__continueStopEditing ) { event.preventDefault(); - return; - } - if ( !self.__continueSnakviewStopEditing ) { + } else if ( !self.__continueStopEditing ) { event.preventDefault(); self.stopEditing( dropValue ); } @@ -224,11 +224,7 @@ */ stopEditing: $.NativeEventHandler( 'stopEditing', { initially: function( e, dropValue ) { - if( - !this.isInEditMode() - || !this.isValid() && !this.isInitialValue() - && !dropValue && !this.__continueStopEditing - ) { + if( !this.isInEditMode() ) { e.cancel(); } @@ -240,8 +236,6 @@ if ( dropValue ) { // If the whole item was pending, remove the whole list item. This has to be // performed in the widget using the snaklistview. - - this.__continueSnakviewStopEditing = false; // Re-create the list view to restore snakviews that have been removed during // editing: @@ -255,8 +249,6 @@ } else if ( this.option( 'value' ) !== null && this.__continueStopEditing ) { var self = this; - this.__continueStopEditing = false; - this.__continueSnakviewStopEditing = true; $.each( this._listview.items(), function( i, item ) { var $item = $( item ), snakview = self._lia.liInstance( $item ); @@ -266,7 +258,7 @@ // After saving, the property should not be editable anymore. snakview.options.locked.property = true; } ); - this.__continueSnakviewStopEditing = false; + this.__continueStopEditing = false; this.enable(); @@ -275,8 +267,7 @@ // Transform toolbar and snak view after save complete this._trigger( 'afterstopediting', null, [ dropValue ] ); - } else if ( !this.option( 'value' ) ) { - this.__continueStopEditing = false; + } else if ( !this.option( 'value' ) && !this.__continueStopEditing ) { // Creating a new snaklistview is managed in the object using the snaklistview (e.g. // in the statementview). Creating a snaklistview will end up in here after having // performed the API call adding the snaklistview's subject (e.g. the reference) to @@ -312,7 +303,9 @@ if ( !( snakList instanceof wb.SnakList ) ) { throw new Error( 'Value has to be an instance of wikibase.SnakList' ); } + this._snakList = snakList; + this.createListView(); return this._snakList; } // getter: @@ -339,10 +332,6 @@ isValid: function() { var self = this, isValid = true; - - if ( this._listview.items().length === 0 ) { - return false; - } $.each( this._listview.items(), function( i, item ) { var snakview = self._lia.liInstance( $( item ) ); diff --git a/lib/resources/jquery.wikibase/jquery.wikibase.statementview.js b/lib/resources/jquery.wikibase/jquery.wikibase.statementview.js index 32e1149..6f44543 100644 --- a/lib/resources/jquery.wikibase/jquery.wikibase.statementview.js +++ b/lib/resources/jquery.wikibase/jquery.wikibase.statementview.js @@ -29,11 +29,13 @@ }, '', // TODO: This toolbar placeholder should be removed from the template. '', // .wb-claim-mainsnak + '', // Qualifiers '', // Rreferences heading '' // List of references ], templateShortCuts: { '$mainSnak': '.wb-claim-mainsnak', + '$qualifiers': '.wb-statement-qualifiers', '$refsHeading': '.wb-statement-references-heading', '$references': '.wb-statement-references' } @@ -45,12 +47,6 @@ * @type jQuery */ $refsHeading: null, - - /** - * DOM node holding the Statement's references. - * @type jQuery - */ - $references: null, /** * Shortcut to the list item adapter in use in the reference view. @@ -212,8 +208,8 @@ } } ) .on( 'listviewenternewitem', function( event, $newLi ) { - // Enter first item into the referenceview. - self._referenceviewLia.liInstance( $newLi ).enterNewItem(); + // Enter first item into the referenceview. + self._referenceviewLia.liInstance( $newLi ).enterNewItem(); } ); // Forward query for listview reference. @@ -255,8 +251,8 @@ revStore = wb.getRevisionStore(), guid = this.value().getGuid(), statement = new wb.Statement( - self.$mainSnak.data( 'snakview' ).snak(), - null, // TODO: Qualifiers + this.$mainSnak.data( 'snakview' ).snak(), + ( this._qualifiers ) ? this._qualifiers.value() : null, this.getReferences(), null, // TODO: Rank guid @@ -269,6 +265,7 @@ // Update model of represented Claim: self._claim = newStatement; + self._qualifiers.value( newStatement.getQualifiers() ); } ); }, @@ -378,6 +375,23 @@ name: 'wikibase.statementview', prototype: $.wikibase.statementview.prototype }, + events: { + statementviewchange: function( event ) { + var $target = $( event.target ), + statementview = $target.data( 'statementview' ), + enable = statementview.isValid() && !statementview.isInitialValue(), + edittoolbar = $target.data( 'edittoolbar' ); + + if ( statementview._qualifiers && ( + !statementview._qualifiers.isValid() + || statementview._qualifiers.isInitialValue() && statementview.isInitialValue() + ) ) { + enable = false + } + + edittoolbar.editGroup.btnSave[ enable ? 'enable' : 'disable' ](); + } + }, options: { interactionWidgetName: $.wikibase.statementview.prototype.widgetName, toolbarParentSelector: '.wb-statement-claim' diff --git a/lib/resources/jquery.wikibase/jquery.wikibase.toolbarcontroller/toolbarcontroller.definitions.js b/lib/resources/jquery.wikibase/jquery.wikibase.toolbarcontroller/toolbarcontroller.definitions.js index b45696c..9ef517b 100644 --- a/lib/resources/jquery.wikibase/jquery.wikibase.toolbarcontroller/toolbarcontroller.definitions.js +++ b/lib/resources/jquery.wikibase/jquery.wikibase.toolbarcontroller/toolbarcontroller.definitions.js @@ -75,9 +75,8 @@ * The selector to locate the node the toolbar shall be initialized on. * If an interaction widget is set, the widget selector will be used. * - eventPrefix - * Prefix the events the toolbar shall listen to will be prefixed with. This refers to - * the "create" event that should trigger the toolbar creation and any other events - * that may be registered via the "events" attribute. + * Prefix the events the toolbar shall listen to will be prefixed with. This only + * refers to the "create" event that should trigger the toolbar creation. * If an interaction widget is defined, the widget's event prefix is used as event * prefix. * - baseClass diff --git a/lib/resources/jquery.wikibase/jquery.wikibase.toolbarcontroller/toolbarcontroller.js b/lib/resources/jquery.wikibase/jquery.wikibase.toolbarcontroller/toolbarcontroller.js index 93dc50d..c8ba56e 100644 --- a/lib/resources/jquery.wikibase/jquery.wikibase.toolbarcontroller/toolbarcontroller.js +++ b/lib/resources/jquery.wikibase/jquery.wikibase.toolbarcontroller/toolbarcontroller.js @@ -27,11 +27,15 @@ * @since 0.4 * * @option addtoolbar {string[]} List of toolbar definition ids/widget names that are registered - * as "addtoolbars" and shall be initialized. + * as "add" toolbars and shall be initialized. * Default: [] * * @option edittoolbar {string[]} List of toolbar definition ids/widget names that are - * registered as "edittoolbars" and shall be initialized. + * registered as "edit" toolbars and shall be initialized. + * Default: [] + * + * @option removetoolbar {string[]} List of toolbar definition ids/widget names that are + * registered as "remove" toolbars and shall be initialized. * Default: [] */ $.widget( 'wikibase.toolbarcontroller', { @@ -41,7 +45,8 @@ */ options: { addtoolbar: [], - edittoolbar: [] + edittoolbar: [], + removetoolbar: [] }, /** @@ -73,8 +78,6 @@ var $initNode = self.element.find( def.selector || ':' + def.widget.fullName ); if ( def.events ) { - var eventPrefix = def.eventPrefix - || ( def.widget ? def.widget.prototype.widgetEventPrefix : '' ); // Toolbars that shall be created upon certain events. $.each( def.events, function( eventName, callbackOrKeyword ) { @@ -96,13 +99,16 @@ } // Create and destroy events have to be defined. - $initNode.on( eventPrefix + eventName, function( event ) { + $initNode.on( eventName, function( event ) { callbackOrKeyword( event, $( event.target ) ); } ); } ); - } else { + } + + if ( !def.events || def.widget ) { $initNode[type]( options ); } + } ); } ); diff --git a/lib/resources/templates.php b/lib/resources/templates.php index ba32dc9..804913b 100644 --- a/lib/resources/templates.php +++ b/lib/resources/templates.php @@ -69,6 +69,7 @@ <div class="wb-claim-mainsnak" dir="auto"> $3 <!-- wb-snak (Main Snak) --> </div> + <div class="wb-claim-qualifiers">$4</div> </div> HTML; @@ -97,12 +98,13 @@ <div class="wb-claim-mainsnak" dir="auto"> $3 <!-- wb-snak (Main Snak) --> </div> + <div class="wb-claim-qualifiers wb-statement-qualifiers">$4</div> </div> - $4 + $5 </div> <div class="wb-statement-references-container"> - <div class="wb-statement-references-heading">$5</div> - <div class="wb-statement-references">$6 <!-- [0,*] wb-reference --></div> + <div class="wb-statement-references-heading">$6</div> + <div class="wb-statement-references">$7 <!-- [0,*] wb-reference --></div> </div> </div> HTML; diff --git a/lib/resources/wikibase.css b/lib/resources/wikibase.css index c1c7254..d66d01f 100644 --- a/lib/resources/wikibase.css +++ b/lib/resources/wikibase.css @@ -598,6 +598,72 @@ /***** /EDIT/NEW CLAIM *****/ +/***** QUALIFIERS *****/ + +.wb-claim-qualifiers { + padding-left: 17em; +} + +.wb-claim-qualifiers .wb-snaklistview .wb-snaklistview-listview .wb-snak-property { + width: 12em; + position: absolute; + font-size: 90%; +} + +.wb-claim-qualifiers .wb-snaklistview .wb-snaklistview-listview .wb-snak-property input { + width: 100%; + font-size: 100%; + top: 0; + position: absolute; +} + +.wb-claim-qualifiers .wb-snaklistview .wb-snaklistview-listview .wb-snak-value-container { + margin-left: 12em; + position: relative; +} + +.wb-claim-qualifiers .wb-snaklistview .wb-snaklistview-listview .wb-snak-value-container .wb-snak-value { + margin-left: 16px; + margin-right: 18em; + word-wrap: break-word; +} + +.wb-claim-qualifiers .wb-snaklistview .wb-snaklistview-listview .wb-snak-value-container .wb-snak-value .valueview-value { + font-size: 90%; +} + +.wb-claim-qualifiers .wb-snaklistview .wb-snaklistview-listview .wb-snak-value-container .wb-snak-typeselector { + left: 0; +} + +.wb-claim-qualifiers .wb-snaklistview .wb-snaklistview-listview .wb-snak-value-container .wb-snak-value .valueview-value textarea { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.wb-claim-qualifiers .wb-snaklistview .wb-snaklistview-listview .wb-snakview { + position: relative; + min-height: 1.8em; + padding-top: 5px; + padding-bottom: 5px; +} + +/* "remove" link at each reference's snak */ +.wb-claim-qualifiers .wb-snaklistview .wb-snaklistview-listview .wb-snakview > .wb-removetoolbar { + position: absolute; + top: 5px; + right: 0; +} + +/* "add" link in one reference's snak list */ +.wb-claim-qualifiers .wb-snaklistview > .wb-addtoolbar { + float: right; + margin-bottom: 1em; +} + +/***** /QUALIFIERS *****/ + /********** /CLAIMS **********/ @@ -624,6 +690,7 @@ .wb-statement-references-container { padding-left: 17em; + clear: both; } .wb-statement-references-container .wb-statement-references-heading { diff --git a/repo/Wikibase.i18n.php b/repo/Wikibase.i18n.php index 7c19609..00cc57e 100644 --- a/repo/Wikibase.i18n.php +++ b/repo/Wikibase.i18n.php @@ -27,6 +27,7 @@ 'wikibase-save' => 'save', 'wikibase-cancel' => 'cancel', 'wikibase-add' => 'add', + 'wikibase-addqualifier' => 'add qualifier', 'wikibase-addreference' => 'add source', 'wikibase-save-inprogress' => 'Saving…', 'wikibase-remove-inprogress' => 'Removing…', @@ -430,6 +431,7 @@ 'wikibase-add' => '[[File:Screenshot WikidataRepo 2012-05-13 F.png|right|0x150px]] [[File:Screenshot WikidataRepo 2012-05-13 A.png|right|0x150px]] This is a generic text used for a link (fig. 3 on [[m:Wikidata/Notes/JavaScript ui implementation]]) that puts the user interface into edit mode for an additional element of some kind.', + 'wikibase-addqualifier' => 'Label of the link to add a qualifier (see [[d:Wikidata:Glossary]]) to a claim or statement.', 'wikibase-addreference' => 'Label of the link to add a reference (see [[d:Wikidata:Glossary]]) to a statement.', 'wikibase-save-inprogress' => '[[File:Screenshot WikidataRepo 2012-05-25 L.png|right|350px]] [[File:Screenshot WikidataRepo 2012-05-25 J.png|right|350px]] diff --git a/repo/includes/EntityView.php b/repo/includes/EntityView.php index 9a213b5..422211a 100644 --- a/repo/includes/EntityView.php +++ b/repo/includes/EntityView.php @@ -509,6 +509,7 @@ $additionalCssClasses, $claim->getGuid(), $mainSnakHtml, + '', // TODO: Qualifiers $this->getHtmlForEditSection( $entity, $lang, '', 'span' ), // TODO: add link to SpecialPage '', // TODO: References heading '' // TODO: References diff --git a/repo/resources/wikibase.ui.entityViewInit.js b/repo/resources/wikibase.ui.entityViewInit.js index 03283f5..4494c33 100644 --- a/repo/resources/wikibase.ui.entityViewInit.js +++ b/repo/resources/wikibase.ui.entityViewInit.js @@ -131,9 +131,9 @@ // BUILD TOOLBARS $( '.wb-entity' ).toolbarcontroller( { - addtoolbar: ['claimlistview', 'claimsection', 'references', 'referenceview-snakview'], + addtoolbar: ['claimlistview', 'claimsection', 'claim-qualifiers-snak', 'references', 'referenceview-snakview'], edittoolbar: ['statementview', 'referenceview'], - removetoolbar: ['referenceview-snakview-remove'] + removetoolbar: ['claim-qualifiers-snak', 'referenceview-snakview-remove'] } ); } -- To view, visit https://gerrit.wikimedia.org/r/55545 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I236bdd0a7e9c8004a4b1a3c2eff83d690985cd05 Gerrit-PatchSet: 8 Gerrit-Project: mediawiki/extensions/Wikibase Gerrit-Branch: master Gerrit-Owner: Henning Snater <henning.sna...@wikimedia.de> Gerrit-Reviewer: Siebrand <siebr...@wikimedia.org> Gerrit-Reviewer: Tobias Gritschacher <tobias.gritschac...@wikimedia.de> Gerrit-Reviewer: jenkins-bot _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits