Thiemo Mättig (WMDE) has submitted this change and it was merged.
Change subject: Implemented jQuery.wikibase.aliasesview
......................................................................
Implemented jQuery.wikibase.aliasesview
jQuery.wikibase.aliasesview replaces the legacy components AliasesEditTool,
EditableAliases,
AliasesInterface and ListInterface.
Change-Id: Ib94eff034cd24b5502dd2e5dc645ab557b51344b
---
M lib/WikibaseLib.hooks.php
M lib/resources/Resources.php
A lib/resources/jquery.wikibase/jquery.wikibase.aliasesview.js
M lib/resources/jquery.wikibase/jquery.wikibase.sitelinklistview.js
M lib/resources/jquery.wikibase/jquery.wikibase.sitelinkview.js
A lib/resources/jquery.wikibase/themes/default/jquery.wikibase.aliasesview.css
M lib/resources/jquery.wikibase/toolbar/toolbareditgroup.js
M lib/resources/templates.php
M lib/resources/wikibase.css
D lib/resources/wikibase.ui.AliasesEditTool.js
D lib/resources/wikibase.ui.PropertyEditTool.EditableAliases.js
D lib/resources/wikibase.ui.PropertyEditTool.EditableValue.AliasesInterface.js
D lib/resources/wikibase.ui.PropertyEditTool.EditableValue.ListInterface.js
M lib/resources/wikibase.ui.PropertyEditTool.css
M
lib/resources/wikibase.utilities/wikibase.utilities.jQuery.ui.tagadata/wikibase.utilities.jQuery.ui.tagadata.js
A lib/tests/qunit/jquery.wikibase/jquery.wikibase.aliasesview.tests.js
D lib/tests/qunit/wikibase.ui.AliasesEditTool.tests.js
D lib/tests/qunit/wikibase.ui.PropertyEditTool.EditableAliases.tests.js
D
lib/tests/qunit/wikibase.ui.PropertyEditTool.EditableValue.ListInterface.tests.js
M repo/includes/View/FingerprintView.php
M repo/resources/Resources.php
M repo/resources/wikibase.ui.entityViewInit.js
M repo/tests/phpunit/includes/View/FingerprintViewTest.php
23 files changed, 915 insertions(+), 1,331 deletions(-)
Approvals:
WikidataJenkins: Verified
Thiemo Mättig (WMDE): Looks good to me, approved
jenkins-bot: Checked
diff --git a/lib/WikibaseLib.hooks.php b/lib/WikibaseLib.hooks.php
index 652333b..ab21842 100644
--- a/lib/WikibaseLib.hooks.php
+++ b/lib/WikibaseLib.hooks.php
@@ -83,16 +83,13 @@
'tests/qunit/wikibase.RepoApi/wikibase.RepoApi.tests.js',
'tests/qunit/wikibase.RepoApi/wikibase.RepoApiError.tests.js',
-
'tests/qunit/wikibase.ui.AliasesEditTool.tests.js',
'tests/qunit/wikibase.ui.DescriptionEditTool.tests.js',
'tests/qunit/wikibase.ui.LabelEditTool.tests.js',
'tests/qunit/wikibase.ui.PropertyEditTool.tests.js',
-
'tests/qunit/wikibase.ui.PropertyEditTool.EditableAliases.tests.js',
'tests/qunit/wikibase.ui.PropertyEditTool.EditableDescription.tests.js',
'tests/qunit/wikibase.ui.PropertyEditTool.EditableLabel.tests.js',
'tests/qunit/wikibase.ui.PropertyEditTool.EditableValue.tests.js',
'tests/qunit/wikibase.ui.PropertyEditTool.EditableValue.Interface.tests.js',
-
'tests/qunit/wikibase.ui.PropertyEditTool.EditableValue.ListInterface.tests.js',
'tests/qunit/wikibase.utilities/wikibase.utilities.ClaimGuidGenerator.tests.js',
'tests/qunit/wikibase.utilities/wikibase.utilities.GuidGenerator.tests.js',
@@ -128,6 +125,15 @@
)
);
+ $testModules['qunit']['jquery.wikibase.aliasesview.tests'] =
$moduleBase + array(
+ 'scripts' => array(
+
'tests/qunit/jquery.wikibase/jquery.wikibase.aliasesview.tests.js',
+ ),
+ 'dependencies' => array(
+ 'jquery.wikibase.aliasesview'
+ ),
+ );
+
$testModules['qunit']['jquery.wikibase.claimgrouplabelscroll.tests'] =
$moduleBase + array(
'scripts' => array(
'tests/qunit/jquery.wikibase/jquery.wikibase.claimgrouplabelscroll.tests.js',
diff --git a/lib/resources/Resources.php b/lib/resources/Resources.php
index bff86d1..8ebf321 100644
--- a/lib/resources/Resources.php
+++ b/lib/resources/Resources.php
@@ -26,9 +26,11 @@
// common styles independent from JavaScript being enabled or
disabled
'wikibase.common' => $moduleTemplate + array(
'styles' => array(
-
'jquery.wikibase/themes/default/jquery.wikibase.sitelinkview.css',
-
'jquery.wikibase/themes/default/jquery.wikibase.sitelinklistview.css',
+ // Order must be hierarchical, do not order
alphabetically
'wikibase.css',
+
'jquery.wikibase/themes/default/jquery.wikibase.aliasesview.css',
+
'jquery.wikibase/themes/default/jquery.wikibase.sitelinklistview.css',
+
'jquery.wikibase/themes/default/jquery.wikibase.sitelinkview.css',
)
),
@@ -298,14 +300,10 @@
'wikibase.ui.PropertyEditTool.js',
'wikibase.ui.PropertyEditTool.EditableValue.js',
'wikibase.ui.PropertyEditTool.EditableValue.Interface.js',
-
'wikibase.ui.PropertyEditTool.EditableValue.ListInterface.js',
-
'wikibase.ui.PropertyEditTool.EditableValue.AliasesInterface.js',
'wikibase.ui.PropertyEditTool.EditableDescription.js',
'wikibase.ui.PropertyEditTool.EditableLabel.js',
-
'wikibase.ui.PropertyEditTool.EditableAliases.js',
'wikibase.ui.LabelEditTool.js',
'wikibase.ui.DescriptionEditTool.js',
- 'wikibase.ui.AliasesEditTool.js',
),
'styles' => array(
'wikibase.ui.PropertyEditTool.css'
@@ -470,6 +468,27 @@
)
),
+ 'jquery.wikibase.aliasesview' => $moduleTemplate + array(
+ 'scripts' => array(
+ 'jquery.wikibase/jquery.wikibase.aliasesview.js'
+ ),
+ 'styles' => array(
+
'jquery.wikibase/themes/default/jquery.wikibase.aliasesview.css',
+ ),
+ 'dependencies' => array(
+ 'jquery.inputautoexpand',
+ 'jquery.ui.TemplatedWidget',
+ 'jquery.wikibase.edittoolbar',
+ 'jquery.wikibase.toolbarcontroller',
+ 'wikibase.RepoApiError',
+ 'wikibase.templates',
+ 'wikibase.utilities.jQuery.ui.tagadata',
+ ),
+ 'messages' => array(
+ 'wikibase-aliases-label'
+ ),
+ ),
+
'jquery.wikibase.sitelinkgroupview' => $moduleTemplate + array(
'scripts' => array(
'jquery.wikibase/jquery.wikibase.sitelinkgroupview.js'
@@ -493,6 +512,7 @@
'jquery.tablesorter',
'jquery.ui.TemplatedWidget',
'jquery.wikibase.addtoolbar',
+ 'jquery.wikibase.edittoolbar',
'jquery.wikibase.listview',
'jquery.wikibase.sitelinkview',
'jquery.wikibase.toolbarcontroller',
diff --git a/lib/resources/jquery.wikibase/jquery.wikibase.aliasesview.js
b/lib/resources/jquery.wikibase/jquery.wikibase.aliasesview.js
new file mode 100644
index 0000000..6fcf683
--- /dev/null
+++ b/lib/resources/jquery.wikibase/jquery.wikibase.aliasesview.js
@@ -0,0 +1,522 @@
+/**
+ * @licence GNU GPL v2+
+ * @author H. Snater < [email protected] >
+ */
+( function( $, mw, wb ) {
+ 'use strict';
+
+ var PARENT = $.ui.TemplatedWidget;
+
+/**
+ * Manages a aliases.
+ * @since 0.5
+ * @extends jQuery.ui.TemplatedWidget
+ *
+ * @option {Object|null} value
+ * Object representing the widget's value.
+ * Structure: { language: <{string}>, aliases: <{string[]}> }
+ *
+ * @option {string} [helpMessage]
+ * Default: mw.msg( 'wikibase-aliases-input-help-message' )
+ *
+ * @options {string} entityId
+ *
+ * @option {wikibase.RepoApi} api
+ *
+ * @option {wikibase.store.EntityStore} entityStore
+ */
+$.widget( 'wikibase.aliasesview', PARENT, {
+ /**
+ * @see jQuery.ui.TemplatedWidget.options
+ */
+ options: {
+ template: 'wikibase-aliasesview',
+ templateParams: [
+ '', // additional class
+ mw.msg( 'wikibase-aliases-label' ), // label
+ '', // list items
+ '' // toolbar
+ ],
+ templateShortCuts: {
+ '$label': '.wikibase-aliasesview-label',
+ '$list': 'ul'
+ },
+ value: null,
+ helpMessage: mw.msg( 'wikibase-aliases-input-help-message' ),
+ entityId: null,
+ api: null
+ },
+
+ /**
+ * @type {boolean}
+ */
+ _isInEditMode: false,
+
+ /**
+ * @see jQuery.ui.TemplatedWidget._create
+ *
+ * @throws {Error} if required parameters are not specified properly.
+ */
+ _create: function() {
+ if( !this.options.entityId || !this.options.api ) {
+ throw new Error( 'Required option(s) missing' );
+ }
+
+ this.options.value = this._checkValue( this.options.value );
+
+ PARENT.prototype._create.call( this );
+
+ this.element.removeClass( 'wb-empty' );
+ this.$label.text( mw.msg( 'wikibase-aliases-label' ) );
+
+ var value = this.options.value;
+
+ if(
+ value && value.aliases.length
+ && this.$list.children( 'li' ).length !==
value.aliases.length
+ ) {
+ this._draw();
+ }
+
+ this.element
+ // TODO: Move that code to a sensible place (see
jQuery.wikibase.entityview):
+ .on( 'aliasesviewafterstartediting.' + this.widgetName,
function( event ) {
+ $( wb ).trigger( 'startItemPageEditMode', [
+ event.target,
+ {
+ exclusive: false,
+ wbCopyrightWarningGravity: 'sw'
+ }
+ ] );
+ } )
+ .on( 'aliasesviewafterstopediting.' + this.widgetName,
function( event, dropValue ) {
+ $( wb ).trigger( 'stopItemPageEditMode', [
+ event.target,
+ { save: dropValue !== true }
+ ] );
+ } );
+ },
+
+ /**
+ * @see jQuery.ui.TemplatedWidget.destroy
+ */
+ destroy: function() {
+ if( this._isInEditMode ) {
+ var self = this;
+
+ this.element.one( this.widgetEventPrefix +
'afterstopediting', function( event ) {
+ PARENT.prototype.destroy.call( self );
+ } );
+
+ this.cancelEditing();
+ } else {
+ PARENT.prototype.destroy.call( this );
+ }
+ },
+
+ /**
+ * Main draw routine.
+ */
+ _draw: function() {
+ this.$list.off( '.' + this.widgetName );
+
+ if( !this._isInEditMode ) {
+ var tagadata = this.$list.data( 'tagadata' );
+
+ if( tagadata ) {
+ tagadata.destroy();
+ }
+
+ this.element.removeClass( 'wb-edit' );
+
+ this.$list.empty();
+ if( !this.options.value ) {
+ return;
+ }
+
+ for( var i = 0; i < this.options.value.aliases.length;
i++ ) {
+ this.$list.append(
+ mw.template(
'wikibase-aliasesview-list-item', this.options.value.aliases[i] )
+ );
+ }
+
+ return;
+ }
+
+ this.element.addClass( 'wb-edit' );
+
+ this._initTagadata();
+ },
+
+ /**
+ * Creates and initializes the tagadata widget.
+ */
+ _initTagadata: function() {
+ var self = this;
+
+ this.$list
+ .tagadata( {
+ animate: false,
+ placeholderText: mw.msg(
'wikibase-alias-edit-placeholder' )
+ } )
+ .on(
+ 'tagadatatagremoved.' + this.widgetName
+ + ' tagadatatagchanged.' + this.widgetName
+ + ' tagadatatagremoved.' + this.widgetName, function(
event ) {
+ self._trigger( 'change' );
+ }
+ );
+
+ var expansionOptions = {
+ expandOnResize: false,
+ comfortZone: 16, // width of .ui-icon
+ maxWidth: function() {
+ // TODO/FIXME: figure out why this requires at
least -17, can't be because of padding + border
+ // which is only 6 for both sides
+ return self.$list.width() - 20;
+ }
+ /*
+ // TODO/FIXME: both solutions are not perfect, when tag
larger than available space either the
+ // input will be auto-resized and not show the whole
text or we still show the whole tag but it
+ // will break the site layout. A solution would be
replacing input with textarea.
+ maxWidth: function() {
+ var tagList = self._getTagadata().tagList;
+ var origCssDisplay = tagList.css( 'display' );
+ tagList.css( 'display', 'block' );
+ var width = tagList.width();
+ tagList.css( 'display', origCssDisplay );
+ return width;
+ }
+ */
+ };
+
+ var tagadata = this.$list.data( 'tagadata' );
+
+ // calculate size for all input elements initially:
+ tagadata.getTags().find( 'input' ).inputautoexpand(
expansionOptions );
+
+ // also make sure that new helper tags will calculate size
correctly:
+ this.$list.on( 'tagadatahelpertagadded.' + this.widgetName,
function( event, tag ) {
+ $( tag ).find( 'input' ).inputautoexpand(
expansionOptions );
+ } );
+ },
+
+ /**
+ * Starts the widget's edit mode.
+ */
+ startEditing: function() {
+ if( this._isInEditMode ) {
+ return;
+ }
+
+ this._isInEditMode = true;
+ this._draw();
+
+ this._trigger( 'afterstartediting' );
+ },
+
+ /**
+ * Stops the widget's edit mode.
+ *
+ * @param {boolean} dropValue
+ */
+ stopEditing: function( dropValue ) {
+ var self = this;
+
+ if( !this._isInEditMode || ( !this.isValid() ||
this.isInitialValue() ) && !dropValue ) {
+ return;
+ }
+
+ if( dropValue ) {
+ this._afterStopEditing( dropValue );
+ return;
+ }
+
+ this.disable();
+
+ this._trigger( 'stopediting', null, [dropValue] );
+
+ // TODO: Performing API interaction should be managed in parent
component (probably
+ // entityview)
+ this._save()
+ .done( function() {
+ self.enable();
+ self._afterStopEditing( dropValue );
+ } )
+ .fail( function( errorCode, details ) {
+ // TODO: API should return an Error object
+ var error = wb.RepoApiError.newFromApiResponse(
errorCode, details, 'save' );
+ self.setError( error );
+ } );
+ },
+
+ /**
+ * @return {jQuery.Promise}
+ */
+ _save: function() {
+ return this.options.api.setAliases(
+ this.options.entityId,
+ wb.getRevisionStore().getAliasesRevision(),
+ this._getNewAliases(),
+ this._getRemovedAliases(),
+ this.options.value.language
+ )
+ .done( function( response ) {
+ wb.getRevisionStore().setAliasesRevision(
response.entity.lastrevid );
+ } );
+ },
+
+ /**
+ * Cancels the widget's edit mode.
+ */
+ cancelEditing: function() {
+ this.stopEditing( true );
+ },
+
+ /**
+ * 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 {string[]}
+ */
+ _getNewAliases: function() {
+ var currentAliases = this.value().aliases,
+ newAliases = [];
+
+ for( var i = 0; i < currentAliases.length; i++ ) {
+ if( $.inArray( currentAliases[i],
this.options.value.aliases ) === -1 ) {
+ newAliases.push( currentAliases[i] );
+ }
+ }
+
+ return newAliases;
+ },
+
+ /**
+ * @return {string[]}
+ */
+ _getRemovedAliases: function() {
+ var currentAliases = this.value().aliases,
+ initialAliases = this.options.value.aliases,
+ removedAliases = [];
+
+ for( var i = 0; i < initialAliases.length; i++ ) {
+ if( $.inArray( initialAliases[i], currentAliases ) ===
-1 ) {
+ removedAliases.push( initialAliases[i] );
+ }
+ }
+
+ return removedAliases;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ isValid: function() {
+ if( !this._isInEditMode ) {
+ return true;
+ }
+
+ return !this.$list.find( '.tagadata-choice-equal' ).length;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ isInitialValue: function() {
+ var initialValue = this.options.value,
+ currentValue = this.value();
+
+ if(
+ currentValue.language !== initialValue.language
+ || currentValue.aliases.length !==
initialValue.aliases.length
+ ) {
+ return false;
+ }
+
+ for( var i = 0; i < currentValue.aliases.length; i++ ) {
+ if( currentValue.aliases[i] !== initialValue.aliases[i]
) {
+ return false;
+ }
+ }
+
+ return true;
+ },
+
+ /**
+ * Toggles error state.
+ *
+ * @param {Error} error
+ */
+ setError: function( error ) {
+ if( error ) {
+ this.element.addClass( 'wb-error' );
+ this._trigger( 'toggleerror', null, [error] );
+ } else {
+ this.element.removeClass( 'wb-error' );
+ this._trigger( 'toggleerror' );
+ }
+ },
+
+ /**
+ * @see jQuery.ui.TemplatedWidget._setOption
+ */
+ _setOption: function( key, value ) {
+ if( key === 'value' ) {
+ value = this._checkValue( value );
+ }
+ return PARENT.prototype._setOption.call( this, key, value );
+ },
+
+ /**
+ * @param {*} value
+ * @return {Object}
+ *
+ * @throws {Error} if value is not defined properly.
+ */
+ _checkValue: function( value ) {
+ if( !$.isPlainObject( value ) ) {
+ throw new Error( 'Value needs to be an object' );
+ } else if( !value.language ) {
+ throw new Error( 'Value needs language to be specified'
);
+ }
+
+ if( !value.aliases ) {
+ value.aliases = [];
+ }
+
+ return value;
+ },
+
+ /**
+ * Gets/Sets the widget's value.
+ *
+ * @param {Object} [value]
+ * @return {Object|undefined}
+ */
+ value: function( value ) {
+ if( value !== undefined ) {
+ this.option( 'value', value );
+ return;
+ }
+
+ if( !this._isInEditMode ) {
+ return this.option( 'value' );
+ }
+
+ var tagadata = this.$list.data( 'tagadata' );
+
+ value = $.map( tagadata.getTags(), function( $tag ) {
+ return tagadata.getTagLabel( $tag );
+ } );
+
+ return {
+ language: this.options.value.language,
+ aliases: value
+ };
+ },
+
+ /**
+ * Puts Keyboard focus on the widget.
+ */
+ focus: function() {
+ if( this._isInEditMode ) {
+ this.$list.data( 'tagadata' ).getHelperTag().find(
'input' ).focus();
+ }
+ },
+
+ /**
+ * @see jQuery.ui.TemplatedWidget.disable
+ */
+ disable: function() {
+ if( this._isInEditMode ) {
+ this.$list.data( 'tagadata' ).disable();
+ }
+
+ return PARENT.prototype.disable.call( this );
+ },
+
+ /**
+ * @see jQuery.ui.TemplatedWidget.enable
+ */
+ enable: function() {
+ if( this._isInEditMode ) {
+ this.$list.data( 'tagadata' ).enable();
+ }
+
+ return PARENT.prototype.enable.call( this );
+ }
+
+} );
+
+$.wikibase.toolbarcontroller.definition( 'edittoolbar', {
+ id: 'aliasesview',
+ events: {
+ aliasesviewcreate: function( event, toolbarcontroller ) {
+ var $aliasesview = $( event.target ),
+ aliasesview = $aliasesview.data( 'aliasesview'
);
+
+ $aliasesview.edittoolbar( {
+ $container: $( '<div/>' ).insertAfter(
$aliasesview.find( 'ul' ) ),
+ interactionWidgetName:
$.wikibase.aliasesview.prototype.widgetName,
+ enableRemove: false
+ } );
+
+ $aliasesview.on( 'keyup', function( event ) {
+ if( aliasesview.option( 'disabled' ) ) {
+ return;
+ }
+ if( event.keyCode === $.ui.keyCode.ESCAPE ) {
+ aliasesview.stopEditing( true );
+ } else if( event.keyCode === $.ui.keyCode.ENTER
) {
+ aliasesview.stopEditing( false );
+ }
+ } );
+
+ $aliasesview.one( 'toolbareditgroupedit', function() {
+
+ toolbarcontroller.registerEventHandler(
+ event.data.toolbar.type,
+ event.data.toolbar.id,
+ aliasesview.widgetEventPrefix +
'change',
+ function( event ) {
+ var $aliasesview = $(
event.target ),
+ aliasesview =
$aliasesview.data( 'aliasesview' ),
+ toolbar =
$aliasesview.data( 'edittoolbar' ).toolbar,
+ $btnSave =
toolbar.editGroup.getButton( 'save' ),
+ btnSave =
$btnSave.data( 'toolbarbutton' ),
+ enable =
aliasesview.isValid() && !aliasesview.isInitialValue();
+
+ btnSave[enable ? 'enable' :
'disable']();
+ }
+ );
+
+ } );
+ },
+ toolbareditgroupedit: function( event, toolbarcontroller ) {
+ var $aliasesview = $( event.target ).closest(
':wikibase-edittoolbar' ),
+ aliasesview = $aliasesview.data( 'aliasesview'
);
+
+ if( !aliasesview ) {
+ return;
+ }
+
+ aliasesview.focus();
+ }
+ }
+} );
+
+}( jQuery, mediaWiki, wikibase ) );
diff --git a/lib/resources/jquery.wikibase/jquery.wikibase.sitelinklistview.js
b/lib/resources/jquery.wikibase/jquery.wikibase.sitelinklistview.js
index 8420185..c4105d7 100644
--- a/lib/resources/jquery.wikibase/jquery.wikibase.sitelinklistview.js
+++ b/lib/resources/jquery.wikibase/jquery.wikibase.sitelinklistview.js
@@ -70,7 +70,7 @@
*/
_create: function() {
if( !this.options.entityId || !this.options.api ||
!this.options.entityStore ) {
- throw new Error( 'Required options missing' );
+ throw new Error( 'Required option(s) missing' );
}
PARENT.prototype._create.call( this );
diff --git a/lib/resources/jquery.wikibase/jquery.wikibase.sitelinkview.js
b/lib/resources/jquery.wikibase/jquery.wikibase.sitelinkview.js
index 287bad2..2a4c848 100644
--- a/lib/resources/jquery.wikibase/jquery.wikibase.sitelinkview.js
+++ b/lib/resources/jquery.wikibase/jquery.wikibase.sitelinkview.js
@@ -90,7 +90,7 @@
*/
_create: function() {
if( !this.options.entityStore || !this.options.helpMessage ) {
- throw new Error( 'Required options missing' );
+ throw new Error( 'Required option(s) missing' );
}
PARENT.prototype._create.call( this );
diff --git
a/lib/resources/jquery.wikibase/themes/default/jquery.wikibase.aliasesview.css
b/lib/resources/jquery.wikibase/themes/default/jquery.wikibase.aliasesview.css
new file mode 100644
index 0000000..b8178fb
--- /dev/null
+++
b/lib/resources/jquery.wikibase/themes/default/jquery.wikibase.aliasesview.css
@@ -0,0 +1,84 @@
+/**
+ * @licence GNU GPL v2+
+ * @author H. Snater < [email protected] >
+ */
+.wikibase-aliasesview,
+.wikibase-aliasesview-empty {
+ float: left; /* necessary for highlighting in edit mode */
+ width: 100%;
+}
+
+/* aliases exclusive helper div containing editable value and its toolbar but
not the
+PropertyEditTool toolbar */
+.wikibase-aliasesview .wikibase-aliasesview-container {
+ display: block !important;
+ padding-left: 10px;
+ padding-right: 19em;
+ position: relative;
+}
+
+.wikibase-aliasesview-label {
+ font-size: 84%; /* using #contentSub font-size */
+ float: left;
+ font-weight: bold;
+ margin-right: 1em;
+ margin-top: 1px; /* even out border of alias values */
+ margin-bottom: -3px; /* IE 7 would not wrap around directly but instead
leave empty space
+ underneath the label
for one line in some cases */
+}
+
+.wikibase-aliasesview.wb-empty .wikibase-aliasesview-label {
+ font-weight: normal;
+}
+
+.wikibase-aliasesview .wikibase-aliasesview-label,
+.wikibase-aliasesview ul {
+ overflow: auto;
+}
+
+.wikibase-aliasesview div {
+ display: inline;
+}
+
+.wikibase-aliasesview ul {
+ margin: 0;
+ padding: 0;
+ line-height: inherit;
+}
+
+.wikibase-aliasesview li {
+ font-size: 84%;
+ float: left;
+ margin: 0.2em 12px 0.2em 0;
+ display: inline;
+ list-style-type: none;
+ border: 1px solid #CCC;
+ padding: 0 12px 0 7px;
+ line-height: 136%;
+ background-color: #F8F8F8;
+}
+
+.wikibase-aliasesview ul.tagadata li {
+ margin: 0.2em 4px 0.2em 0;
+}
+
+.wikibase-aliasesview ul.tagadata li.tagadata-choice {
+ line-height: 136%;
+}
+
+.wikibase-aliasesview .tagadata-choice input {
+ padding-top: 0 !important;
+ padding-bottom: 0 !important;
+}
+
+.wikibase-aliasesview.wb-edit {
+ background-color: #D6F3FF;
+ white-space: normal; /* required by FF for not(!) wrapping toolbar when
there is only one line of aliases */
+}
+
+.wikibase-aliasesview.wb-edit ul {
+ /* since the aliases ul list is cloned in JS, its stashed pendant will
be visible as box on the
+ edit mode highlight colour in non-Webkit browsers without making the bg
colour transparent */
+ background: transparent;
+ font-size: 1em;
+}
diff --git a/lib/resources/jquery.wikibase/toolbar/toolbareditgroup.js
b/lib/resources/jquery.wikibase/toolbar/toolbareditgroup.js
index ba2f526..ae7ce1e 100644
--- a/lib/resources/jquery.wikibase/toolbar/toolbareditgroup.js
+++ b/lib/resources/jquery.wikibase/toolbar/toolbareditgroup.js
@@ -398,7 +398,8 @@
'class': 'mw-help-field-hint',
style: 'display:inline;text-decoration:none;', // TODO:
Get rid of inline styles.
html: ' ' // TODO find nicer way to hack Webkit
browsers to display tooltip image (see also css)
- } ) );
+ } ) )
+ .toolbarlabel( { stateChangeable: false } );
// Clone buttons:
clone._buttons.edit = this._buttons.edit ?
this._buttons.edit.data( 'toolbarbutton' ).clone() : null;
diff --git a/lib/resources/templates.php b/lib/resources/templates.php
index 4f7e266..2dbc89b 100644
--- a/lib/resources/templates.php
+++ b/lib/resources/templates.php
@@ -190,24 +190,20 @@
<span class="wb-value-supplement">$1</span>
HTML;
- $templates['wb-aliases-wrapper'] =
+ $templates['wikibase-aliasesview'] =
<<<HTML
-<div class="wb-aliases $1">
- <div class="wb-gridhelper">
- <span class="wb-aliases-label $2">$3</span>
- $4
+<div class="wikibase-aliasesview $1">
+ <div class="wikibase-aliasesview-container">
+ <span class="wikibase-aliasesview-label">$2</span>
+ <ul class="wikibase-aliasesview-list">$3</ul>
+ <!-- wb-toolbar -->$4
</div>
</div>
HTML;
- $templates['wb-aliases'] =
+ $templates['wikibase-aliasesview-list-item'] =
<<<HTML
-<ul class="wb-aliases-container">$1</ul>
-HTML;
-
- $templates['wb-alias'] =
-<<<HTML
-<li class="wb-aliases-alias">$1</li>
+<li class="wikibase-aliasesview-list-item">$1</li>
HTML;
$templates['wb-editsection'] =
diff --git a/lib/resources/wikibase.css b/lib/resources/wikibase.css
index d22cf5b..8b76efb 100644
--- a/lib/resources/wikibase.css
+++ b/lib/resources/wikibase.css
@@ -266,87 +266,6 @@
/********** /LABEL & DESCRIPTION **********/
-/********** ALIASES **********/
-
-.wb-aliases,
-.wb-aliases-empty {
- float: left; /* necessary for highlighting in edit mode */
- width: 100%;
-}
-
-/* aliases exclusive helper div containing editable value and its toolbar but
not the
-PropertyEditTool toolbar */
-.wb-aliases .wb-gridhelper {
- display: block !important;
- padding-left: 10px;
- padding-right: 19em;
- position: relative;
-}
-
-.wb-aliases-label {
- font-size: 84%; /* using #contentSub font-size */
- float: left;
- font-weight: bold;
- margin-right: 1em;
- margin-top: 1px; /* even out border of alias values */
- margin-bottom: -3px; /* IE 7 would not wrap around directly but instead
leave empty space
- underneath the label
for one line in some cases */
-}
-
-.wb-aliases-empty .wb-aliases-label {
- font-weight: normal;
-}
-
-.wb-aliases-label,
-.wb-aliases ul {
- overflow: auto;
-}
-
-.wb-aliases div {
- display: inline;
-}
-
-.wb-aliases ul {
- margin: 0;
- padding: 0;
- line-height: inherit;
-}
-
-.wb-aliases li {
- font-size: 84%;
- float: left;
- margin: 0.2em 12px 0.2em 0;
- display: inline;
- list-style-type: none;
- border: 1px solid #CCC;
- padding: 0 12px 0 7px;
- line-height: 136%;
- background-color: #F8F8F8;
-}
-
-/* the aliases edit tool has to be customized due to different font sizes of
the aliases and its
-toolbar; furthermore, the PropertyEditTool toolbar (which is displayed only
when there are no
-aliases) shall be vertically be aligned to the baseline of the first row of
aliases (just like the
-EditableValue's "edit" button when aliases exist) */
-
-.wb-aliases .wb-editsection {
- /* aliases PropertyEditTool toolbar should be on the same vertical
level than its label since
- it is only displayed when there are no aliases (other
PropertyEditToolbars appear below the last
- editable value */
- position: absolute;
- top: 0;
- right: 0;
- width: 18em;
-}
-
-.wb-aliases > .wikibase-toolbar {
- width: 18em;
- float: right;
-}
-
-/********** /ALIASES **********/
-
-
/********** TERMS **********/
.wb-terms .wb-value {
diff --git a/lib/resources/wikibase.ui.AliasesEditTool.js
b/lib/resources/wikibase.ui.AliasesEditTool.js
deleted file mode 100644
index 30db1bf..0000000
--- a/lib/resources/wikibase.ui.AliasesEditTool.js
+++ /dev/null
@@ -1,177 +0,0 @@
-/**
- * JavaScript for 'Wikibase' edit form for an items aliases
- * @see https://www.mediawiki.org/wiki/Extension:Wikibase
- *
- * @licence GNU GPL v2+
- * @author Daniel Werner < daniel.werner at wikimedia.de >
- * @author H. Snater < [email protected] >
- */
-( function( mw, wb, util, $ ) {
-'use strict';
-var PARENT = wb.ui.PropertyEditTool;
-
-/**
- * Module for 'Wikibase' extensions user interface functionality for editing
an items aliases.
- * @constructor
- * @since 0.1
- */
-wb.ui.AliasesEditTool = util.inherit( PARENT , {
- /**
- * Initializes the edit form for the aliases.
- * This should normally be called directly by the constructor.
- *
- * @see wb.ui.PropertyEditTool._init
- */
- _init: function( subject, options ) {
- var self = this;
-
- // setting default options
- options = $.extend( {}, PARENT.prototype._options, {
- /**
- * @see
wikibase.ui.PropertyEditTool.allowsMultipleValues
- */
- allowsMultipleValues: false,
-
- /**
- * @see wikibase.ui.PropertyEditTool.allowsFullErase
- */
- allowsFullErase: true
- }, options );
-
- // call PropertyEditTool's init():
- PARENT.prototype._init.call( this, subject, options );
-
- // add class specific to this ui element:
- this._subject.addClass( 'wb-ui-aliasesedittool' );
-
- $( this._toolbar.$btnAdd ).on( 'toolbarbuttonaction', function(
event ) {
- // Hide add button when hitting it since edit mode
toolbar will appear.
- self._toolbar.hide();
- } );
-
- if( this._editableValues.length > 0 &&
this._editableValues[0].getValue().length > 0 ) {
- this._toolbar.hide(); // hide add button if there are
any aliases
- }
-
- // Very special handling of special AliasesEditTool on special
case when no aliases are
- // defined and edit mode is triggered:
- $( wikibase ).on(
- 'startItemPageEditMode',
- $.proxy(
- function( event, origin ) {
- if ( !this.getOption(
'allowsMultipleValues' ) ) {
- if (
- this instanceof
wb.ui.AliasesEditTool &&
- origin instanceof
wb.ui.PropertyEditTool.EditableAliases
- ) {
- this._subject.addClass(
this.UI_CLASS + '-ineditmode' );
- }
- }
- }, this
- )
- );
-
- },
-
- /**
- * @see wikibase.ui.PropertyEditTool.EditableValue._getValuesParent
- *
- * @return jQuery
- */
- _getValuesParent: function() {
- // grid layout helper constructed in the init() function
- return this._subject.children( '.wb-gridhelper:first' );
- },
-
- /**
- * @see wb.ui.PropertyEditTool._initSingleValue
- */
- _initSingleValue: function( valueElem, options, tooltipOptions ) {
- var editableValue =
wb.ui.PropertyEditTool.prototype._initSingleValue.apply( this, arguments );
-
- // show add button when leaving edit mode without having any
aliases at all
- $( editableValue ).on( 'afterStopEditing', $.proxy( function(
event ) {
- if ( this.getValues().length === 0 ) {
- this._toolbar.show();
- }
- }, this ) );
-
- return editableValue;
- },
-
- /**
- * @see wikibase.ui.PropertyEditTool._newEmptyValueDOM()
- *
- * @return {jQuery}
- */
- _newEmptyValueDOM: function() {
- return mw.template( 'wb-aliases', '' );
- },
-
- /**
- * @see wb.ui.PropertyEditTool._buildSingleValueToolbar
- */
- _buildSingleValueToolbar: function( options ) {
- var self = this,
- toolbar =
PARENT.prototype._buildSingleValueToolbar.call( this, options );
-
- // determine whether to show or hide the add button when
cancelling edit mode
- $( toolbar.$editGroup.data( 'toolbareditgroup' ).getButton(
'cancel' ) ).on(
- 'toolbarbuttonaction',
- function( event ) {
- if ( self.getValues()[0].getValue()[0].length
=== 0 ) { // no aliases at all
- self._toolbar.show();
- self._editableValues[0].destroy();
-
self._editableValues[0].getSubject().remove(); // subject will be re-created
via add button
- self._editableValues = [];
- } else {
- self._toolbar.hide();
- }
- }
- );
-
- return toolbar;
- },
-
- /**
- * @see wikibase.ui.PropertyEditTool._getValueElems
- *
- * @return jQuery
- */
- _getValueElems: function() {
- return this._subject.find( '.wb-aliases-container:first' );
- },
-
- /**
- * @see wikibase.ui.PropertyEditTool.getPropertyName
- *
- * @return string 'aliases'
- */
- getPropertyName: function() {
- return 'aliases';
- },
-
- /**
- * @see wikibase.ui.PropertyEditTool.getEditableValuePrototype
- *
- * @return wikibase.ui.PropertyEditTool.EditableAliases
- */
- getEditableValuePrototype: function() {
- return wb.ui.PropertyEditTool.EditableAliases;
- }
-
-} );
-
-/**
- * Returns the basic DOM structure sufficient for a new
wikibase.ui.AliasesEditTool
- * @static
- *
- * @return {jQuery}
- */
-wb.ui.AliasesEditTool.getEmptyStructure = function() {
- return mw.template(
- 'wb-aliases-wrapper', '', '', mw.message(
'wikibase-aliases-label' ).escaped(), ''
- );
-};
-
-} )( mediaWiki, wikibase, util, jQuery );
diff --git a/lib/resources/wikibase.ui.PropertyEditTool.EditableAliases.js
b/lib/resources/wikibase.ui.PropertyEditTool.EditableAliases.js
deleted file mode 100644
index 13cb774..0000000
--- a/lib/resources/wikibase.ui.PropertyEditTool.EditableAliases.js
+++ /dev/null
@@ -1,175 +0,0 @@
-/**
- * @licence GNU GPL v2+
- * @author Daniel Werner
- */
-( function( mw, wb, util, $ ) {
-'use strict';
-/* jshint camelcase: false */
-
-var PARENT = wb.ui.PropertyEditTool.EditableValue;
-
-/**
- * Serves the input interface for an items aliases, extends EditableValue.
- * @constructor
- * @extends wb.ui.PropertyEditTool.EditableValue
- * @since 0.1
- */
-var SELF = wb.ui.PropertyEditTool.EditableAliases = util.inherit( PARENT, {
-
- API_VALUE_KEY: 'aliases',
-
- /**
- * @see wb.ui.PropertyEditTool.EditableValue._options
- */
- _options: $.extend( {}, PARENT.prototype._options, {
- inputHelpMessageKey: 'wikibase-aliases-input-help-message'
- } ),
-
- /**
- * @see wikibase.ui.PropertyEditTool.EditableValue._init
- *
- * @param {jQuery} subject
- * @param {Object} options
- * @param {jQuery.wikibase.toolbar} toolbar
- */
- _init: function( subject, options, toolbar ) {
- var newSubject = $( '<span>' );
-
- // Do not use $.replaceWith() since it drops widget data:
- $( this._subject ).after( newSubject );
- newSubject.append( $( this._subject ).detach() );
-
- // overwrite subject // TODO: really not that nice, is it?
- this._subject = newSubject;
-
- PARENT.prototype._init.call( this, newSubject, options, toolbar
);
- },
-
- /**
- * @see
wikibase.ui.PropertyEditTool.EditableValue._interfaceHandler_onInputRegistered
- *
- * @param relatedInterface
wikibase.ui.PropertyEditTool.EditableValue.Interface
- */
- _interfaceHandler_onInputRegistered: function( relatedInterface ) {
- if( relatedInterface.isInEditMode() ) {
-
PARENT.prototype._interfaceHandler_onInputRegistered.call( this,
relatedInterface );
-
- // Always enable cancel button since it is alright to
have an empty value:
- this._toolbar.$editGroup.data( 'toolbareditgroup'
).enableButton( 'cancel' );
- }
- },
-
- /**
- * @see
wikibase.ui.PropertyEditTool.EditableValue._getValueFromApiResponse
- */
- _getValueFromApiResponse: function( response ) {
- if ( response[ this.API_VALUE_KEY ]
- && $.isArray( response[ this.API_VALUE_KEY ][
window.mw.config.get( 'wgUserLanguage' ) ] )
- ) {
- var values = [];
- $.each( response[ this.API_VALUE_KEY ][
window.mw.config.get( 'wgUserLanguage' ) ], function( i, item ) {
- values.push( item.value );
- } );
- return values;
- } else {
- return null;
- }
- },
-
- /**
- * @see
wikibase.ui.PropertyEditTool.EditableValue._setRevisionIdFromApiResponse
- */
- _setRevisionIdFromApiResponse: function( response ) {
- wb.getRevisionStore().setAliasesRevision( response.lastrevid );
- return true;
- },
-
- /**
- * Removes injected nodes in addition to parent's destroy routine.
- *
- * @see wikibase.ui.PropertyEditTool.EditableValue._destroy
- */
- _destroy: function() {
- var originalSubject = this._subject.find( 'ul:first' );
-
- // div injected in this._buildInterfaces()
- this._subject.find( 'ul:first' ).parent().replaceWith(
this._subject.find( 'ul:first' ) );
-
- // span injected in this._init()
- this._subject.replaceWith( this._subject.children() );
-
- this._subject = originalSubject;
-
- PARENT.prototype._destroy.call( this );
- },
-
- /**
- * Sets a value
- * @see wikibase.ui.PropertyEditTool.EditableValue
- *
- * @param {array} value to set
- * @return Array set value
- */
- setValue: function( value ) {
- if( $.isArray( value ) ) {
- this._interfaces[0].setValue( value );
- }
- return this.getValue();
- },
-
- /**
- * @see wikibase.ui.PropertyEditTool.EditableValue.showError
- */
- showError: function( error, $anchor ) {
- // EditableAliases has no "remove" button. However, when saving
with an empty value, a
- // "remove" action is implied. But since there ist no "remove"
button to attach an error
- // tooltip to, the "save" button shall be used even when a
"remove" action has been
- // triggered.
- $anchor = this._toolbar.$editGroup.data( 'toolbareditgroup'
).getButton( 'save' );
- PARENT.prototype.showError.call( this, error, $anchor );
- },
-
- /**
- * Calling the corresponding method in the wikibase.RepoApi
- *
- * @return {jQuery.Promise}
- */
- queryApi: function() {
- return this._api.setAliases(
- mw.config.get( 'wbEntityId' ),
- wb.getRevisionStore().getAliasesRevision(),
- this._interfaces[0].getNewItems(),
- this._interfaces[0].getRemovedItems(),
- this.getValueLanguageContext()
- );
- },
-
- /**
- * @see wikibase.ui.PropertyEditTool.EditableValue.preserveEmptyForm
- * @var bool
- */
- preserveEmptyForm: false
-} );
-
-/**
- * @see wb.ui.PropertyEditTool.EditableValue.newFromDom
- */
-SELF.newFromDom = function( subject, options, toolbar ) {
- var ev = wb.ui.PropertyEditTool.EditableValue,
- $subject = $( subject ),
- $interfaceParent = $( '<div/>' );
-
- options = options || {};
- options.valueLanguageContext =
- options.valueLanguageContext ||
ev.getValueLanguageContextFromDom( $subject );
-
- // Do not use $.replaceWith() since it drops widget data:
- $subject.filter( 'ul:first' ).after( $interfaceParent );
- $interfaceParent.append( $subject.filter( 'ul:first' ).detach() );
-
- var aliasesInterface = new ev.AliasesInterface( $interfaceParent );
-
- return new SELF( $interfaceParent, options, aliasesInterface );
-};
-
-}( mediaWiki, wikibase, util, jQuery ) );
diff --git
a/lib/resources/wikibase.ui.PropertyEditTool.EditableValue.AliasesInterface.js
b/lib/resources/wikibase.ui.PropertyEditTool.EditableValue.AliasesInterface.js
deleted file mode 100644
index 3b582c9..0000000
---
a/lib/resources/wikibase.ui.PropertyEditTool.EditableValue.AliasesInterface.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * @licence GNU GPL v2+
- * @author Daniel Werner
- */
-( function( mw, wb, util ) {
-'use strict';
-var PARENT = wb.ui.PropertyEditTool.EditableValue.ListInterface;
-
-/**
- * Serves the input interface for an items aliases and handles the conversion
between the pure html representation
- * and the interface itself in both directions.
- * @constructor
- * @see wikibase.ui.PropertyEditTool.EditableValue.ListInterface
- * @since 0.1
- */
-wb.ui.PropertyEditTool.EditableValue.AliasesInterface = util.inherit( PARENT, {
- /**
- * @see wikibase.ui.PropertyEditTool.ListInterface.UI_VALUE_PIECE_CLASS
- * @const
- */
- UI_VALUE_PIECE_CLASS: 'wb-aliases-alias',
-
- /**
- * @see wikibase.ui.PropertyEditTool.EditableValue.Interface._options
- * @type {Object}
- */
- _options: {
- /**
- * @see
wikibase.ui.PropertyEditTool.EditableValue.Interface.inputPlaceholder
- * @type {String}
- */
- inputPlaceholder: mw.msg( 'wikibase-alias-edit-placeholder' )
- }
-} );
-
-} )( mediaWiki, wikibase, util );
diff --git
a/lib/resources/wikibase.ui.PropertyEditTool.EditableValue.ListInterface.js
b/lib/resources/wikibase.ui.PropertyEditTool.EditableValue.ListInterface.js
deleted file mode 100644
index ffe9329..0000000
--- a/lib/resources/wikibase.ui.PropertyEditTool.EditableValue.ListInterface.js
+++ /dev/null
@@ -1,369 +0,0 @@
-/**
- * @licence GNU GPL v2+
- * @author Daniel Werner
- */
-( function( mw, wb, util, $ ) {
-'use strict';
-/* jshint camelcase: false */
-
-var PARENT = wb.ui.PropertyEditTool.EditableValue.Interface;
-
-/**
- * Serves the input interface for a list of strings and handles the conversion
between the pure html representation
- * and the interface itself in both directions. All values of the list belong
together and must be edited at the same
- * time.
- * @constructor
- * @see wb.ui.PropertyEditTool.EditableValue.Interface
- * @since 0.1
- */
-wb.ui.PropertyEditTool.EditableValue.ListInterface = util.inherit( PARENT, {
- /**
- * Css class which will be attached to all pieces of a value set with
this interface.
- * @const
- */
- UI_VALUE_PIECE_CLASS:
'wb-ui-propertyedittool-editablevaluelistinterface-piece',
-
- /**
- * @see
wikibase.ui.PropertyEditTool.EditableValue.Interface._initInputElement
- */
- _initInputElement: function() {
- PARENT.prototype._initInputElement.call( this );
- /*
- applying auto-expansion mechanism has to be done after
tagadata's tagList has been placed within
- the DOM since no css rules of the specified css classes are
applied by then - respectively jQuery's
- .css() function would return unexpected results
- */
- var self = this;
- if ( $.fn.inputautoexpand ) {
- var expansionOptions = {
- expandOnResize: false,
- comfortZone: 16, // width of .ui-icon
- maxWidth: function() {
- // TODO/FIXME: figure out why this
requires at least -17, can't be because of padding + border
- // which is only 6 for both sides
- return self._inputElem.width() - 20;
- }
- /*
- // TODO/FIXME: both solutions are not perfect,
when tag larger than available space either the
- // input will be auto-resized and not show the
whole text or we still show the whole tag but it
- // will break the site layout. A solution would
be replacing input with textarea.
- maxWidth: function() {
- var tagList =
self._getTagadata().tagList;
- var origCssDisplay = tagList.css(
'display' );
- tagList.css( 'display', 'block' );
- var width = tagList.width();
- tagList.css( 'display', origCssDisplay
);
- return width;
- }
- */
- };
-
- // calculate size for all input elements initially:
- this._getTagadata().tagList.children( 'li' ).find(
'input' ).inputautoexpand( expansionOptions );
-
- // also make sure that new helper tags will calculate
size correctly:
- this._inputElem.on( 'tagadatahelpertagadded', function(
e, tag ) {
- $( tag ).find( 'input' ).inputautoexpand(
expansionOptions );
- } );
- }
- },
-
- /**
- * create input element and initialize autocomplete
- * @see
wikibase.ui.PropertyEditTool.EditableValue.Interface._buildInputElement
- *
- * @return jQuery
- */
- _buildInputElement: function() {
- // nodes will be removed and replaced with genereated input
interface, so we clone them for initialization:
- var inputElement = this._subject.children( 'ul:first' ).clone(),
- self = this;
-
- // additional UI class
- this._subject.addClass(
'wb-ui-propertyedittool-editablevaluelistinterface' );
-
- // Get events from all input elements of tagadata and register
them here.
- // NOTE: not yet all events registered, register on demand.
- // ToDo: this is not nice, we should use use proper
event-delegation instead
- inputElement
- .on( 'tagadatataginserted', function( e, tag ) {
- $( tag ).find( 'input' )
- .on( 'keypress',function( event ) {
- self._onKeyPressed( event );
- } )
- .on( 'keyup', function( event ) {
- self._onKeyUp( event );
- } );
- } );
-
- inputElement.tagadata( {
- animate: false, // FIXME: when animated set to true,
something won't work in there, fails silently then
- placeholderText: this.getOption( 'inputPlaceholder' ),
- tagRemoved: $.proxy( this._onInputRegistered, this )
- } )
- // register event after initial tags were added on tag-a-data
initialization!
- .on( 'tagadatatagadded tagadatatagchanged', $.proxy( function(
e, tag ) {
- this._onInputRegistered();
- }, this ) );
-
- return inputElement;
- },
-
- /**
- * @see
wikibase.ui.PropertyEditTool.EditableValue.Interface._destroyInputElement
- */
- _destroyInputElement: function() {
- this._getTagadata().destroy();
- this._subject.children( 'li' ).removeClass(
this.UI_VALUE_PIECE_CLASS + '-new' );
- this._inputElem = null;
- },
-
- /**
- * Convenience function for getting the 'tagadata' jQuery plugin data
related to the _inputElem
- *
- * @return wikibase.utilities.jQuery.ui.tagadata|null
- */
- _getTagadata: function() {
- if( ! this._inputElem ) {
- return null;
- }
- return this._inputElem.data( 'tagadata' );
- },
-
- /**
- * @see
wikibase.ui.PropertyEditTool.EditableValue.Interface._getValue_inEditMode
- *
- * @return string[]
- */
- _getValue_inEditMode: function() {
- var tagadata = this._getTagadata(),
- labels = [];
-
- if ( tagadata !== undefined ) {
- var values = tagadata.getTags();
- for( var i in values ) {
- labels.push( tagadata.getTagLabel( values[i] )
);
- }
- }
- return labels;
- },
-
- /**
- * @see
wikibase.ui.PropertyEditTool.EditableValue.Interface._getValue_inNonEditMode
- *
- * @return string[]
- */
- _getValue_inNonEditMode: function() {
- var values = [],
- valList = this._subject.children( 'ul:first' );
-
- valList.children( 'li' ).each( function() {
- values.push( $( this ).text() );
- } );
-
- return values;
- },
-
- /**
- * @see
wikibase.ui.PropertyEditTool.EditableValue.Interface._setValue_inEditMode
- *
- * @param {string[]} value
- * @return bool
- */
- _setValue_inEditMode: function( value ) {
- this._getTagadata().removeAll();
- var self = this;
- $.each( value, function( i, val ) {
- self._getTagadata().createTag( val,
self.UI_VALUE_PIECE_CLASS );
- } );
- return false; // onInputRegistered event will be thrown by
tagadata.onTagAdded
- },
-
- /**
- * @see
wikibase.ui.PropertyEditTool.EditableValue.Interface._setValue_inNonEditMode
- *
- * @param {string[]} value
- * @return bool
- */
- _setValue_inNonEditMode: function( value ) {
- var valList = this._subject.children( 'ul:first' ),
- self = this;
-
- // FIXME: Emptying valList causes property edit tool's toolbar
elements to be dropped
- // without clearing their references in the property edit tool
instance. Just removing the
- // <li> nodes does not work either since the property edit
tool's toolbar should actually
- // be removed. Accessing valList.data(
'wb-ui-propertyedittool' ) as a workaround.
- if( valList.data( 'wb-ui-propertyedittool' ) ) {
- valList.data( 'wb-ui-propertyedittool'
)._toolbar.destroy();
- valList.data( 'wb-ui-propertyedittool' )._toolbar =
null;
- }
- valList.empty();
-
- $.each( value, function( i, val ) {
- valList.append( $( '<li>', {
- 'class': self.UI_VALUE_PIECE_CLASS,
- 'text': val
- } ) );
- } );
-
- return true; // trigger onInputRegistered event
- },
-
- /**
- * Returns all items added to the list since edit mode has been entered.
- * If not in edit mode, this will simply return an empty array.
- *
- * @return Array
- */
- getNewItems: function() {
- return $( this.getValue() ) // current items...
- .not( this.getInitialValue() ) // ...without initial
items
- .toArray();
- },
-
- /**
- * Returns all items removed from the list since edit mode has been
entered.
- * If not in edit mode, this will simply return an empty array.
- *
- * @return Array
- */
- getRemovedItems: function() {
- return $( this.getInitialValue() ) // initial items...
- .not( this.getValue() ) // ...without current items
- .toArray();
- },
-
- /**
- * @see wikibase.ui.PropertyEditTool.EditableValue.setFocus
- */
- setFocus: function() {
- if( this._getTagadata() !== null ) {
- this._getTagadata().getHelperTag().find( 'input'
).focus();
- }
- },
-
- /**
- * @see wikibase.ui.PropertyEditTool.EditableValue.removeFocus
- */
- removeFocus: function() {
- if( this._getTagadata() !== null ) {
- this._getTagadata().getHelperTag().find( 'input'
).blur();
- }
- },
-
- /**
- * @see
wikibase.ui.PropertyEditTool.EditableValue.Interface.valueCompare
- *
- * Compares all values of the two lists, normalizes the lists first.
This means the values can be in random and
- * still be considered equal.
- *
- * @param {string[]} value1
- * @param {string[]} value2 [optional] if not given, this will check
whether value1 is empty
- * @return bool true for equal/empty, false if not
- */
- valueCompare: function( value1, value2 ) {
- var normalVal1 = this.normalize( value1 );
-
- if( !$.isArray( value2 ) ) {
- // check for empty value1
- return normalVal1.length < 1;
- }
-
- var normalVal2 = this.normalize( value2 );
-
- if( normalVal1.length !== normalVal2.length ) {
- return false;
- }
-
- for( var i in normalVal1 ) {
- if( normalVal1[ i ] !== normalVal2[ i ] ) {
- return false;
- }
- }
- return true;
- },
-
- /**
- * @see wikibase.ui.PropertyEditTool.EditableValue.Interface.isEmpty
- *
- * @return bool whether this interface is empty
- */
- isEmpty: function() {
- return this.getValue().length === 0;
- },
-
- /**
- * @see wikibase.ui.PropertyEditTool.EditableValue.Interface.validate
- *
- * @return bool whether this interface is valid
- */
- validate: function( value ) {
- var normalized = this.normalize( value );
- return normalized.length > 0;
- },
-
- /**
- * Normalizes a set of values. If any of the values pieces is invalid,
the piece will be removed.
- * If in the end no piece is left because all pieces were invalid, an
empty array will be returned.
- *
- * @param {string[]} value
- * @return String[] all parts of the value which are valid, can be an
empty array
- */
- normalize: function( value ) {
- var validValue = [],
- self = this;
-
- $.each( value, function( i, val ) {
- val = self.normalizePiece( val );
- if( val !== null ) {
- // add valid values to result
- validValue.push( val );
- }
- } );
- return validValue;
- },
-
- /**
- * Validates a piece of a list value.
- *
- * @param {string} value
- * @return Bool
- */
- validatePiece: function( value ) {
- var normalized = this.normalizePiece( value );
- return normalized !== null;
- },
-
- /**
- * Normalizes a string so it is sufficient for setting it as value for
this interface.
- * This will be done automatically when using setValue().
- * In case the given value is invalid, null will be returned.
- *
- * @param {string} value
- * @return String|null
- */
- normalizePiece: function( value ) {
- var normalized = PARENT.prototype.normalize.call( this, value );
- if( normalized === '' ) {
- return null;
- }
- return normalized;
- },
-
- /**
- * @see wb.utilities.ui.StatableObject._setState
- */
- _setState: function( state ) {
- if ( this._getTagadata() !== null ) {
- if ( state === this.STATE.DISABLED ) {
- this._getTagadata().disable();
- } else {
- this._getTagadata().enable();
- }
- }
- return true;
- }
-
-} );
-
-} )( mediaWiki, wikibase, util, jQuery );
diff --git a/lib/resources/wikibase.ui.PropertyEditTool.css
b/lib/resources/wikibase.ui.PropertyEditTool.css
index 842eec1..81f9820 100644
--- a/lib/resources/wikibase.ui.PropertyEditTool.css
+++ b/lib/resources/wikibase.ui.PropertyEditTool.css
@@ -97,35 +97,6 @@
/***** /DESCRIPTION *****/
-
-/********** ALIASES **********/
-
-.wb-aliases ul.tagadata li {
- margin: 0.2em 4px 0.2em 0;
-}
-
-.wb-aliases ul.tagadata li.tagadata-choice {
- line-height: 136%;
-}
-
-.wb-aliases .tagadata-choice input {
- padding-top: 0 !important;
- padding-bottom: 0 !important;
-}
-
-.wb-aliases .wb-ui-propertyedittool-editablevalue-ineditmode {
- white-space: normal; /* required by FF for not(!) wrapping toolbar when
there is only one line of aliases */
-}
-
-.wb-aliases .wb-ui-propertyedittool-editablevalue-ineditmode ul {
- /* since the aliases ul list is cloned in JS, its stashed pendant will
be visible as box on the
- edit mode highlight colour in non-Webkit browsers without making the bg
colour transparent */
- background: transparent;
- font-size: 1em;
-}
-
-/********** /ALIASES **********/
-
/********** TAGADATA **********/
ul.tagadata {
diff --git
a/lib/resources/wikibase.utilities/wikibase.utilities.jQuery.ui.tagadata/wikibase.utilities.jQuery.ui.tagadata.js
b/lib/resources/wikibase.utilities/wikibase.utilities.jQuery.ui.tagadata/wikibase.utilities.jQuery.ui.tagadata.js
index 6d8482c..1040c93 100644
---
a/lib/resources/wikibase.utilities/wikibase.utilities.jQuery.ui.tagadata/wikibase.utilities.jQuery.ui.tagadata.js
+++
b/lib/resources/wikibase.utilities/wikibase.utilities.jQuery.ui.tagadata/wikibase.utilities.jQuery.ui.tagadata.js
@@ -112,33 +112,31 @@
},
/**
- * Returns the nodes of all Tags currently assigned. To get the
actual text, use getTagLabel() on them.
- * If there is an empty tag for inserting a new tag, this won't
be returned by this. Use getHelperTag() instead.
- * If tags have a conflict (same tag exists twice in the list)
only one DOM node in the result will represent
- * all of these conflicted tags.
+ * Returns the nodes of all tags currently assigned. To get the
actual text, use
+ * getTagLabel() on them.
+ * Empty tags are not returned, getHelperTag() may be used to
receive empty tags.
+ * If tags conflict (same tag exists twice) only one of the
corresponding DOM nodes is
+ * returned.
*
- * @return jQuery[]
+ * @return {jQuery}
*/
getTags: function() {
- // Returns an array of tag string values
var self = this,
- tags = [],
+ $tags = $(),
usedLabels = [];
this.tagList.children( '.tagadata-choice' ).each(
function() {
- // check if already removed but still assigned
till animations end. if so, don't add tag!
+ // Check if already removed but still assigned
till animations end:
if( !$( this ).hasClass(
'tagadata-choice-removed' ) ) {
var tagLabel = self.getTagLabel( this );
- if( tagLabel !== '' // don't want the
empty helper tag...
- && $.inArray( tagLabel,
usedLabels ) < 0 // ... or anything twice (in case of conflicts)
- ) {
- tags.push( this );
+ if( tagLabel !== '' && $.inArray(
tagLabel, usedLabels ) === -1 ) {
+ $tags = $tags.add( this );
usedLabels.push( tagLabel );
}
}
} );
- return tags;
+ return $tags;
},
/**
diff --git
a/lib/tests/qunit/jquery.wikibase/jquery.wikibase.aliasesview.tests.js
b/lib/tests/qunit/jquery.wikibase/jquery.wikibase.aliasesview.tests.js
new file mode 100644
index 0000000..4470ac7
--- /dev/null
+++ b/lib/tests/qunit/jquery.wikibase/jquery.wikibase.aliasesview.tests.js
@@ -0,0 +1,212 @@
+/**
+ * @licence GNU GPL v2+
+ * @author H. Snater < [email protected] >
+ */
+
+( function( $, jQuery, QUnit ) {
+'use strict';
+
+/**
+ * @param {Object} [options]
+ * @return {jQuery}
+ */
+var createAliasesview = function( options ) {
+ options = $.extend( {
+ entityId: 'i am an entity id',
+ api: 'i am an api',
+ value: {
+ language: 'en',
+ aliases: ['a', 'b', 'c']
+ }
+ }, options || {} );
+
+ var $aliasesview = $( '<div/>' )
+ .addClass( 'test_aliasesview' )
+ .appendTo( 'body' )
+ .aliasesview( options );
+
+ $aliasesview.data( 'aliasesview' )._save = function() {
+ return $.Deferred().resolve().promise();
+ };
+
+ return $aliasesview;
+};
+
+QUnit.module( 'jquery.wikibase.aliasesview', QUnit.newMwEnvironment( {
+ teardown: function() {
+ $( '.test_aliasesview' ).each( function() {
+ var $aliasesview = $( this ),
+ aliasesview = $aliasesview.data( 'aliasesview'
);
+
+ if( aliasesview ) {
+ aliasesview.destroy();
+ }
+
+ $aliasesview.remove();
+ } );
+ }
+} ) );
+
+QUnit.test( 'Create & destroy', function( assert ) {
+ assert.throws(
+ function() {
+ createAliasesview( { value: null } );
+ },
+ 'Throwing error when trying to initialize widget without a
value.'
+ );
+
+ var $aliasesview = createAliasesview(),
+ aliasesview = $aliasesview.data( 'aliasesview' );
+
+ assert.ok(
+ aliasesview !== undefined,
+ 'Created widget'
+ );
+
+ aliasesview.destroy();
+
+ assert.ok(
+ $aliasesview.data( 'aliasesview' ) === undefined,
+ 'Destroyed widget.'
+ );
+} );
+
+QUnit.test( 'startEditing() & stopEditing()', 5, function( assert ) {
+ var $aliasesview = createAliasesview(),
+ aliasesview = $aliasesview.data( 'aliasesview' );
+
+ $aliasesview
+ .on( 'aliasesviewafterstartediting', function( event ) {
+ assert.ok(
+ true,
+ 'Started edit mode.'
+ );
+ } )
+ .on( 'aliasesviewafterstopediting', function( event, dropValue ) {
+ assert.ok(
+ true,
+ 'Stopped edit mode.'
+ );
+ } );
+
+ aliasesview.startEditing();
+
+ assert.ok(
+ aliasesview.$list.data( 'tagadata' ) !== undefined,
+ 'Instantiated tagadata widget.'
+ );
+
+ aliasesview.startEditing(); // should not trigger event
+ aliasesview.stopEditing( true );
+ aliasesview.stopEditing( true ); // should not trigger event
+ aliasesview.stopEditing(); // should not trigger event
+
+ aliasesview.startEditing();
+
+ // TODO: aliasesview's isValid() should not query for the class.
tagadata should have a public
+ // function to check for conflicts.
+ aliasesview.$list.data( 'tagadata' ).getTags().first().addClass(
'tagadata-choice-equal' );
+
+ aliasesview.stopEditing(); // should not trigger event
+
+ aliasesview.$list.data( 'tagadata' ).getTags().first().removeClass(
'tagadata-choice-equal' )
+ .find( 'input' ).val( 'd' );
+
+ aliasesview.stopEditing();
+} );
+
+QUnit.test( 'isValid()', function( assert ) {
+ var $aliasesview = createAliasesview(),
+ aliasesview = $aliasesview.data( 'aliasesview' );
+
+ aliasesview.startEditing();
+
+ assert.ok(
+ aliasesview.isValid(),
+ 'Verified isValid() returning true.'
+ );
+
+ // TODO: aliasesview's isValid() should not query for the class.
tagadata should have a public
+ // function to check for conflicts.
+ aliasesview.$list.data( 'tagadata' ).getTags().first().addClass(
'tagadata-choice-equal' );
+
+ assert.ok(
+ !aliasesview.isValid(),
+ 'Verified isValid() returning false.'
+ );
+} );
+
+QUnit.test( 'isInitialValue()', function( assert ) {
+ var $aliasesview = createAliasesview(),
+ aliasesview = $aliasesview.data( 'aliasesview' );
+
+ aliasesview.startEditing();
+
+ assert.ok(
+ aliasesview.isInitialValue(),
+ 'Verified isInitialValue() returning true.'
+ );
+
+ aliasesview.$list.data( 'tagadata' ).getTags().first().find( 'input'
).val( 'changed' );
+
+ assert.ok(
+ !aliasesview.isInitialValue(),
+ 'Verified isInitialValue() returning false after changing
value.'
+ );
+
+ aliasesview.$list.data( 'tagadata' ).getTags().first().find( 'input'
).val( 'a' );
+
+ assert.ok(
+ aliasesview.isInitialValue(),
+ 'Verified isInitialValue() returning true after resetting to
initial value.'
+ );
+} );
+
+QUnit.test( 'setError()', function( assert ) {
+ var $aliasesview = createAliasesview(),
+ aliasesview = $aliasesview.data( 'aliasesview' );
+
+ $aliasesview
+ .on( 'aliasesviewtoggleerror', function( event, error ) {
+ assert.ok(
+ true,
+ 'Triggered "toggleerror" event.'
+ );
+ } );
+
+ aliasesview.setError();
+} );
+
+QUnit.test( 'value()', function( assert ) {
+ var $aliasesview = createAliasesview(),
+ aliasesview = $aliasesview.data( 'aliasesview' );
+
+ assert.throws(
+ function() {
+ aliasesview.value( null );
+ },
+ 'Trying to set no value fails.'
+ );
+
+ aliasesview.value( {
+ language: 'de',
+ aliases: ['x', 'y']
+ } );
+
+ assert.ok(
+ aliasesview.value().language === 'de' &&
aliasesview.value().aliases.length === 2,
+ 'Set new value.'
+ );
+
+ aliasesview.value( {
+ language: 'en',
+ aliases: []
+ } );
+
+ assert.ok(
+ aliasesview.value().language === 'en' &&
aliasesview.value().aliases.length === 0,
+ 'Set another value.'
+ );
+} );
+
+}( jQuery, wikibase, QUnit ) );
diff --git a/lib/tests/qunit/wikibase.ui.AliasesEditTool.tests.js
b/lib/tests/qunit/wikibase.ui.AliasesEditTool.tests.js
deleted file mode 100644
index d347462..0000000
--- a/lib/tests/qunit/wikibase.ui.AliasesEditTool.tests.js
+++ /dev/null
@@ -1,92 +0,0 @@
-/**
- * QUnit tests for aliases edit tool
- * @see https://www.mediawiki.org/wiki/Extension:Wikibase
- *
- * @since 0.1
- *
- * @licence GNU GPL v2+
- * @author Daniel Werner
- */
-( function( mw, wb, $, QUnit ) {
- 'use strict';
- QUnit.module( 'wikibase.ui.AliasesEditTool', QUnit.newWbEnvironment( {
- setup: function() {
- /**
- * Holds the original dom structure the AliasesEditTool
was initialized with
- * @var jQuery
- */
- var initialStructure =
wb.ui.AliasesEditTool.getEmptyStructure();
- this.initialStructureMembers =
initialStructure.children();
- this.subject = new wb.ui.AliasesEditTool(
initialStructure, { api: {} } );
-
- QUnit.assert.ok(
- this.subject instanceof wb.ui.AliasesEditTool,
- 'instantiated AliasesEditTool'
- );
- },
- teardown: function() {
- var self = this;
- this.subject.destroy();
-
- // basic check whether initial structure was restored
- var hasInitialStructure = true;
- this.initialStructureMembers.each( function() {
- hasInitialStructure = hasInitialStructure && $(
this ).parent().is( self.subject.getSubject() );
- } );
-
- QUnit.assert.ok(
- hasInitialStructure,
- 'DOM nodes from initial aliases edit tool are
in the right place again'
- );
-
- QUnit.assert.equal(
- this.initialStructureMembers.length +
this.subject.getValues().length,
- self.subject.getSubject().children().length,
- 'No additional DOM nodes left (except those of
inserted values)'
- );
-
- this.subject = null;
- this.initialStructureMembers = null;
- }
-
- } ) );
-
- // base for following tests, creates some values
- var initAliasesTest = function( assert ) {
- var newVal = this.subject.enterNewValue( [ 'alias 1', 'two',
'three' ] );
- assert.ok(
- newVal instanceof
wb.ui.PropertyEditTool.EditableAliases,
- 'Value entered has instance of EditableAlias'
- );
- };
-
- // This is the same as the next test, but the next one does additional
stuff, so the destroy() in teardown
- // might fail independently, depending on the edit tools state.
- QUnit.test( 'Test with creating new EditableAliases', initAliasesTest );
-
- QUnit.test( 'Test creating and removing EditableAliases from edit
tool', function( assert ) {
- initAliasesTest.call( this, assert );
-
- var aliasesValue = this.subject.getValues()[0];
-
- aliasesValue.triggerApi = function( deferred, apiAction ) { //
override AJAX API call
- // dummy response
- deferred.resolve( {
- entity: {
- id: 'someid',
- type: 'item',
- lastrevid: 1234
- },
- success: 1
- } ).promise();
- };
- aliasesValue.remove();
-
- assert.equal(
- this.subject.getValues().length,
- 0,
- 'Empty after removing EditableAliases instance'
- );
- } );
-
-}( mediaWiki, wikibase, jQuery, QUnit ) );
diff --git
a/lib/tests/qunit/wikibase.ui.PropertyEditTool.EditableAliases.tests.js
b/lib/tests/qunit/wikibase.ui.PropertyEditTool.EditableAliases.tests.js
deleted file mode 100644
index d22a2cc..0000000
--- a/lib/tests/qunit/wikibase.ui.PropertyEditTool.EditableAliases.tests.js
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- * QUnit tests for PropertyEditTool.EditableAliases component
- * @see https://www.mediawiki.org/wiki/Extension:Wikibase
- *
- * @since 0.1
- *
- * @licence GNU GPL v2+
- * @author H. Snater <[email protected]>
- */
-
-( function( wb, $, QUnit, undefined ) {
- 'use strict';
-
- /**
- * Factory for creating a new EditableAliases object suited for testing.
- *
- * @return wb.ui.PropertyEditTool.EditableAliases
- */
- var newTestEditableAliases = function() {
- var $node = $( '<ul/>', { id: 'parent' } ).appendTo( 'body' );
- var propertyEditTool = new wb.ui.PropertyEditTool( $node, {
api: {} } );
- var subject =
wb.ui.PropertyEditTool.EditableAliases.newFromDom( $node, { api: {} } );
- var toolbar = propertyEditTool._buildSingleValueToolbar();
- subject.setToolbar( toolbar );
- return subject;
- };
-
- QUnit.module( 'wikibase.ui.PropertyEditTool.EditableAliases',
QUnit.newWbEnvironment( {
- setup: function() {
- this.values = [ 'a', 'b', 'c', 'd' ];
- this.string = 'somestring';
- },
- teardown: function() {}
- } ) );
-
- QUnit.test( 'basic test', function( assert ) {
-
- var subject = newTestEditableAliases();
-
- assert.ok(
- subject._interfaces.length === 1
- && subject._interfaces[0] instanceof
wb.ui.PropertyEditTool.EditableValue.AliasesInterface,
- 'initialized one interface'
- );
-
- assert.equal(
- subject.getValue()[0].length,
- 0,
- 'no value set'
- );
-
- assert.equal(
- subject.setValue( this.values )[0].length,
- this.values.length,
- 'set values'
- );
-
- assert.equal(
- subject.setValue( this.string )[0].length,
- this.values.length,
- 'tried to set invalid value'
- );
-
- assert.equal(
- subject.setValue( [] )[0].length,
- 0,
- 'set empty value'
- );
-
- subject.destroy();
-
- assert.equal(
- subject._toolbar,
- null,
- 'destroyed toolbar'
- );
-
- assert.equal(
- subject._interfaces,
- null,
- 'destroyed interfaces'
- );
-
- } );
-
-}( wikibase, jQuery, QUnit ) );
diff --git
a/lib/tests/qunit/wikibase.ui.PropertyEditTool.EditableValue.ListInterface.tests.js
b/lib/tests/qunit/wikibase.ui.PropertyEditTool.EditableValue.ListInterface.tests.js
deleted file mode 100644
index cbe62de..0000000
---
a/lib/tests/qunit/wikibase.ui.PropertyEditTool.EditableValue.ListInterface.tests.js
+++ /dev/null
@@ -1,208 +0,0 @@
-/**
- * QUnit tests for input interface for property edit tool which is handling
lists
- * @see https://www.mediawiki.org/wiki/Extension:Wikibase
- *
- * @since 0.1
- *
- * @licence GNU GPL v2+
- * @author Daniel Werner
- */
-
-( function( wb, $, QUnit, undefined ) {
- 'use strict';
-
- /**
- * Factory for creating a new ListInterface suited for testing.
- *
- * @param {jQuery} [$node]
- * @return {wb.ui.PropertyEditTool.EditableValue.ListInterface}
- */
- var newTestListInterface = function( $node ) {
- if ( $node === undefined ) {
- $node = $(
-
'<div><ul><li>Y</li><li>Z</li><li><!--empty--></li><li>A</li></ul></div>',
- { id: 'subject' }
- );
- }
- return new wb.ui.PropertyEditTool.EditableValue.ListInterface(
$node );
- };
-
- QUnit.module(
'wikibase.ui.PropertyEditTool.EditableValue.ListInterface',
QUnit.newWbEnvironment() );
-
- QUnit.test( 'basic', function( assert ) {
- var $node = $(
-
'<div><ul><li>Y</li><li>Z</li><li><!--empty--></li><li>A</li></ul></div>',
- { id: 'subject' }
- );
- var subject = newTestListInterface( $node );
-
- assert.ok(
- subject._subject[0] === $node[0],
- 'validated subject'
- );
-
- assert.ok(
- !subject.isEmpty(),
- 'not considered empty'
- );
-
- assert.equal(
- subject.getValue().join( '|' ),
- 'Y|Z|A',
- 'getValue() value equals initial value but sorted'
- );
-
- assert.equal(
- subject.setValue( [ '3', '2', '', '1' ] ).join( '|' ),
- '3|2|1',
- 'set new value, normalized it'
- );
-
- subject.destroy();
-
- assert.equal(
- subject.site,
- null,
- 'destroyed object'
- );
- } );
-
- QUnit.test( 'valueCompare()', function( assert ) {
- var subject = newTestListInterface();
-
- assert.ok(
- subject.valueCompare( [ 'a', 'b' ], [ 'a', 'b' ] ),
- 'simple strings, different order, equal'
- );
-
- assert.ok(
- !subject.valueCompare( [ 'a', 'b' ], [ 'a', 'b', 'c' ]
),
- 'more values in first argument, not equal'
- );
-
- assert.ok(
- !subject.valueCompare( [ 'a', 'b', 'c' ], [ 'a', 'b' ]
),
- 'more values in second argument, not equal'
- );
-
- assert.ok(
- !subject.valueCompare( [ 'a' ] ),
- 'value given, not empty'
- );
-
- assert.ok(
- subject.valueCompare( [] ),
- 'empty array considered empty'
- );
-
- assert.ok(
- subject.valueCompare( [ '', '' ] ),
- 'array with empty strings, considered empty'
- );
- } );
-
- QUnit.test( 'checking for new/removed values during edit mode',
function( assert ) {
- var subject = newTestListInterface();
- /**
- * Creates a new ListInterface, sets items initially, then
starts edit mode and changes the set of items.
- * After this the getRemovedItems() and getNewItems() functions
will be tested.
- *
- * @param initialItems Array Items set before edit mode
- * @param setItems Array Items set during edit mode
- * @param addedItems Array
- * @param removedItems Array
- */
- var addRemoveItemsInEditModeTest = function( initialItems,
setItems, addedItems, removedItems ) {
- assert.ok(
- subject.valueCompare(
- subject.setValue( initialItems ),
- initialItems
- ),
- 'Items [' + initialItems.toString() + '] set
properly (outside edit mode)'
- );
-
- assert.ok(
- subject.startEditing(),
- 'Started edit mode'
- );
-
- assert.ok(
- subject.valueCompare(
- subject.setValue( setItems ),
- setItems
- ),
- 'Set values [' + setItems.toString() + '] in
edit mode'
- );
-
- assert.deepEqual(
- subject.getNewItems(),
- addedItems,
- 'items [' + addedItems.toString() + '] are
recognized as new items by getNewItems()'
- );
-
- assert.deepEqual(
- subject.getRemovedItems(),
- removedItems,
- 'items [' + removedItems.toString() + '] are
recognized as new items by getRemovedItems()'
- );
-
- assert.ok(
- !subject.stopEditing(false), // close edit mode
for next test
- 'Stopped edit mode'
- );
- };
-
- addRemoveItemsInEditModeTest(
- [], // initial
- [ 'a', 'b' ], // set after entering edit mode
- [ 'a', 'b' ], // recognized as added
- [] // recognized as removed
- );
- addRemoveItemsInEditModeTest(
- [ 'a', 'b', 'c' ],
- [],
- [],
- [ 'a', 'b', 'c' ]
- );
- addRemoveItemsInEditModeTest(
- [ 'a', 'b', 'c' ],
- [ 'a' ],
- [],
- [ 'b', 'c' ]
- );
- addRemoveItemsInEditModeTest(
- [ 'a' ],
- [ 'a', 'b', 'c' ],
- [ 'b', 'c' ],
- []
- );
- addRemoveItemsInEditModeTest(
- [],
- [],
- [],
- []
- );
- addRemoveItemsInEditModeTest(
- [ 'a', 'b', 'c' ],
- [ 'b', 'x', 'y' ],
- [ 'x', 'y' ],
- [ 'a', 'c' ]
- );
- } );
-
- QUnit.test( 'checking for new/removed values while not in edit mode',
function( assert ) {
- var subject = newTestListInterface();
-
- assert.deepEqual(
- subject.getNewItems(),
- [],
- 'getNewItems() returns empty array in non-edit mode'
- );
- assert.deepEqual(
- subject.getRemovedItems(),
- [],
- 'getRemovedItems() returns empty array in non-edit mode'
- );
- } );
-
-}( wikibase, jQuery, QUnit ) );
diff --git a/repo/includes/View/FingerprintView.php
b/repo/includes/View/FingerprintView.php
index 5f7575b..be5c1fe 100644
--- a/repo/includes/View/FingerprintView.php
+++ b/repo/includes/View/FingerprintView.php
@@ -146,21 +146,23 @@
$aliasesHtml = '';
$aliases = $aliasGroups->getByLanguage(
$this->languageCode )->getAliases();
foreach ( $aliases as $alias ) {
- $aliasesHtml .= wfTemplate( 'wb-alias',
htmlspecialchars( $alias ) );
+ $aliasesHtml .= wfTemplate(
+ 'wikibase-aliasesview-list-item',
+ htmlspecialchars( $alias )
+ );
}
- $aliasesList = wfTemplate( 'wb-aliases', $aliasesHtml );
- return wfTemplate( 'wb-aliases-wrapper',
- '',
+ return wfTemplate( 'wikibase-aliasesview',
'',
wfMessage( 'wikibase-aliases-label'
)->escaped(),
- $aliasesList . $editSection
+ $aliasesHtml,
+ '<div>' . $editSection . '</div>'
);
} else {
- return wfTemplate( 'wb-aliases-wrapper',
- 'wb-aliases-empty',
- 'wb-value-empty',
+ return wfTemplate( 'wikibase-aliasesview',
+ 'wb-empty',
wfMessage( 'wikibase-aliases-empty'
)->escaped(),
+ '',
$editSection
);
}
diff --git a/repo/resources/Resources.php b/repo/resources/Resources.php
index d8a72a0..e06381c 100644
--- a/repo/resources/Resources.php
+++ b/repo/resources/Resources.php
@@ -27,6 +27,7 @@
'mediawiki.api',
'mediawiki.user',
'wikibase.ui.PropertyEditTool',
+ 'jquery.wikibase.aliasesview',
'jquery.wikibase.entityview',
'jquery.wikibase.toolbarcontroller',
'jquery.wikibase.wbtooltip',
diff --git a/repo/resources/wikibase.ui.entityViewInit.js
b/repo/resources/wikibase.ui.entityViewInit.js
index 8927603..9203e70 100644
--- a/repo/resources/wikibase.ui.entityViewInit.js
+++ b/repo/resources/wikibase.ui.entityViewInit.js
@@ -62,18 +62,6 @@
registerEditRestrictionHandlers();
if( mw.config.get( 'wbEntity' ) !== null ) {
- // if there are no aliases yet, the DOM structure for
creating new ones is created manually since it is not
- // needed for running the page without JS
- $( '.wb-aliases-empty' )
- .each( function() {
- $( this ).replaceWith(
wb.ui.AliasesEditTool.getEmptyStructure() );
- } );
-
- // edit tool for aliases:
- $( '.wb-aliases' ).each( function() {
- new wb.ui.AliasesEditTool( this, { api: repoApi
} );
- } );
-
// BUILD CLAIMS VIEW:
// Note: $.entityview() only works for claims right
now, the goal is to use it for more
var $claims = $( '.wb-claims' ).first(),
@@ -259,6 +247,20 @@
var entityStore = new wb.store.EntityStore( abstractedRepoApi );
wb.compileEntityStoreFromMwConfig( entityStore );
+ // TODO: Integrate into entityview
+ $( '.wikibase-aliasesview' )
+ .toolbarcontroller( {
+ edittoolbar: ['aliasesview']
+ } )
+ .aliasesview( {
+ value: {
+ language: mw.config.get( 'wgUserLanguage' ),
+ aliases: entity.getAliases( mw.config.get(
'wgUserLanguage' ) )
+ },
+ entityId: entity.getId(),
+ api: repoApi
+ } );
+
// FIXME: Initializing entityview on $claims leads to the claim
section inserted as
// child of $claims. It should be direct child of ".wb-entity".
$claims.entityview( {
@@ -321,7 +323,7 @@
// it to a sensible place.
$( wb )
.on( 'startItemPageEditMode', function( event, target, options
) {
- $( ':wikibase-sitelinklistview' )
+ $( ':wikibase-aliasesview, :wikibase-sitelinklistview' )
.find( ':wikibase-toolbar' )
.not( $( target ).find( ':wikibase-toolbar' ) )
.each( function() {
@@ -329,6 +331,9 @@
} );
} )
.on( 'stopItemPageEditMode', function( event, target, options )
{
+ $( ':wikibase-aliasesview' ).find( ':wikibase-toolbar'
).each( function() {
+ $( this ).data( 'toolbar' ).enable();
+ } );
$( ':wikibase-sitelinklistview' ).each( function() {
var $sitelinklistview = $( this ),
sitelinklistview =
$sitelinklistview.data( 'sitelinklistview' );
diff --git a/repo/tests/phpunit/includes/View/FingerprintViewTest.php
b/repo/tests/phpunit/includes/View/FingerprintViewTest.php
index fd05f5e..28e954d 100644
--- a/repo/tests/phpunit/includes/View/FingerprintViewTest.php
+++ b/repo/tests/phpunit/includes/View/FingerprintViewTest.php
@@ -4,9 +4,7 @@
use MessageCache;
use Wikibase\DataModel\Entity\ItemId;
-use Wikibase\DataModel\Term\AliasGroup;
use Wikibase\DataModel\Term\Fingerprint;
-use Wikibase\DataModel\Term\Term;
use Wikibase\Repo\View\FingerprintView;
use Wikibase\Repo\View\SectionEditLinkGenerator;
@@ -134,38 +132,30 @@
$noAliases->removeAliasGroup( 'en' );
return array(
- array( Fingerprint::newEmpty(), 'No' ),
- array( $noLabel, 'No label' ),
- array( $noDescription, 'No description' ),
- array( $noAliases, 'No aliases' ),
+ array( Fingerprint::newEmpty(), array(
'wb-value-empty', 'wb-empty' ), 'No' ),
+ array( $noLabel, array( 'wb-value-empty' ), 'No label'
),
+ array( $noDescription, array( 'wb-value-empty' ), 'No
description' ),
+ array( $noAliases, array( 'wb-empty' ), 'No aliases' ),
);
}
/**
* @dataProvider emptyFingerprintProvider
*/
- public function testGetHtml_isMarkedAsEmptyValue( Fingerprint
$fingerprint ) {
+ public function testGetHtml_isMarkedAsEmptyValue( Fingerprint
$fingerprint, array $classes ) {
$fingerprintView = $this->getFingerprintView();
$html = $fingerprintView->getHtml( $fingerprint );
- $this->assertContains( 'wb-value-empty', $html );
- }
-
- public function testGetHtml_isMarkedAsEmptyAliases() {
- $fingerprintView = $this->getFingerprintView();
- $fingerprint = $this->getFingerprint();
- $fingerprint->removeAliasGroup( 'en' );
- $html = $fingerprintView->getHtml( $fingerprint );
-
- $this->assertContains( 'wb-aliases-empty', $html );
+ foreach ( $classes as $class ) {
+ $this->assertContains( $class, $html );
+ }
}
public function testGetHtml_isNotMarkedAsEmpty() {
$fingerprintView = $this->getFingerprintView();
$html = $fingerprintView->getHtml( $this->getFingerprint() );
- $this->assertNotContains( 'wb-value-empty', $html );
- $this->assertNotContains( 'wb-aliases-empty', $html );
+ $this->assertNotContains( 'wb-empty', $html );
}
/**
@@ -206,7 +196,7 @@
/**
* @dataProvider emptyFingerprintProvider
*/
- public function testGetHtml_containsIsEmptyPlaceholders( Fingerprint
$fingerprint, $message ) {
+ public function testGetHtml_containsIsEmptyPlaceholders( Fingerprint
$fingerprint, array $classes, $message ) {
$fingerprintView = $this->getFingerprintView();
$html = $fingerprintView->getHtml( $fingerprint );
--
To view, visit https://gerrit.wikimedia.org/r/153621
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Ib94eff034cd24b5502dd2e5dc645ab557b51344b
Gerrit-PatchSet: 20
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Henning Snater <[email protected]>
Gerrit-Reviewer: Adrian Lang <[email protected]>
Gerrit-Reviewer: Thiemo Mättig (WMDE) <[email protected]>
Gerrit-Reviewer: WikidataJenkins <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits