Daniel Werner has uploaded a new change for review.
https://gerrit.wikimedia.org/r/57738
Change subject: (bug 45002) additional experts for jQuery.valueview
......................................................................
(bug 45002) additional experts for jQuery.valueview
* Introduction of a "BifidExpert" which is an abstract valueview expert
definition which requires
two other expert constructors in an implementation. The bifid expert will
choose one of the two
other experts depending on the valueview's current mode. This allows greater
flexibility when
defining new experts and allows for sharing code more efficiently.
* SuggestedStringValue expert which is basically a StringValue expert plus
suggester jQuery
widget on top. Also see the TODOs in the documentation.
* Introduces a "StaticDom" expert which can be used together with the
"BifidExpert".
* Reintroduction of special handling for string data values that should match
the CommonsMedia
data type definition. This is done with a CommonsMediaType expert. This
expert is combining the
three experts described above.
* Added the commons media support to MediaWiki's default expert factory.
Change-Id: Ibf778f2ab544ec51f8f9574eb32aea82a5707caf
---
M ValueView/ValueView.resources.mw.php
M ValueView/ValueView.resources.php
A ValueView/resources/jquery.valueview/valueview.BifidExpert.js
A
ValueView/resources/jquery.valueview/valueview.experts/experts.CommonsMediaType.js
A ValueView/resources/jquery.valueview/valueview.experts/experts.StaticDom.js
A
ValueView/resources/jquery.valueview/valueview.experts/experts.SuggestedStringValue.js
M ValueView/resources/mw.ext.valueView.js
7 files changed, 424 insertions(+), 0 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/DataValues
refs/changes/38/57738/1
diff --git a/ValueView/ValueView.resources.mw.php
b/ValueView/ValueView.resources.mw.php
index 55227f3..8af3193 100644
--- a/ValueView/ValueView.resources.mw.php
+++ b/ValueView/ValueView.resources.mw.php
@@ -49,6 +49,7 @@
'dependencies' => array(
'jquery.valueview',
'jquery.valueview.experts.stringvalue',
+ 'jquery.valueview.experts.commonsmediatype'
),
),
diff --git a/ValueView/ValueView.resources.php
b/ValueView/ValueView.resources.php
index 9964c8c..f8c6032 100644
--- a/ValueView/ValueView.resources.php
+++ b/ValueView/ValueView.resources.php
@@ -143,6 +143,19 @@
'jquery.inputAutoExpand',
),
),
+
+ 'jquery.valueview.experts.commonsmediatype' => $moduleTemplate
+ array(
+ 'scripts' => array(
+ 'jquery.valueview/valueview.BifidExpert.js', //
todo: define separate modules
+
'jquery.valueview/valueview.experts/experts.StaticDom.js',
+
'jquery.valueview/valueview.experts/experts.SuggestedStringValue.js',
+
'jquery.valueview/valueview.experts/experts.CommonsMediaType.js',
+ ),
+ 'dependencies' => array(
+ 'jquery.valueview.experts.stringvalue',
+ 'jquery.ui.suggester',
+ ),
+ ),
);
} );
diff --git a/ValueView/resources/jquery.valueview/valueview.BifidExpert.js
b/ValueView/resources/jquery.valueview/valueview.BifidExpert.js
new file mode 100644
index 0000000..04c0007
--- /dev/null
+++ b/ValueView/resources/jquery.valueview/valueview.BifidExpert.js
@@ -0,0 +1,167 @@
+/**
+ * @file
+ * @ingroup ValueView
+ * @licence GNU GPL v2+
+ * @author Daniel Werner < [email protected] >
+ */
+( function( dv, vp, $, vv ) {
+ 'use strict';
+
+ var PARENT = vv.Expert;
+
+ /**
+ * Abstract definition of a Valueview expert whose responsibilities are
shared by two valueview
+ * experts; one taking over during edit mode, one being responsible
while in static mode.
+ *
+ * @since 0.1
+ *
+ * @abstract
+ * @constructor
+ * @extends jQuery.valueview.Expert
+ */
+ vv.BifidExpert = dv.util.inherit( PARENT, {
+ /**
+ * Constructor for the valueview expert responsible during
static mode.
+ * @type Function
+ */
+ _staticExpert: null,
+
+ /**
+ * Options map, the constructor of "_staticExpert" will be
initialized with.
+ */
+ _staticExpertOptions: null,
+
+ /**
+ * Constructor for the valueview expert responsible during edit
mode.
+ * @type Function
+ */
+ _editableExpert: null,
+
+ /**
+ * Options map, the constructor of "_editableExpert" will be
initialized with.
+ */
+ _editableExpertOptions: null,
+
+ /**
+ * The expert currently used internally. Either an instance of
the constructor given in the
+ * "_editableExpert" or "_staticExpert" field.
+ * @type jQuery.valueview.Expert
+ */
+ _currentExpert: null,
+
+ /**
+ * @see jQuery.valueview.Expert._init
+ */
+ _init: function() {
+ this._updateExpert();
+ },
+
+ /**
+ * Will check whether the current expert is the right one for
the related view's current
+ * mode. If not, the expert will be changed. Returns whether or
not the expert has been
+ * updated.
+ *
+ * @since 0.1
+ *
+ * @return boolean
+ */
+ _updateExpert: function() {
+ var NewExpertConstructor, newExpertOptions;
+
+ if( this._viewState.isInEditMode() ) {
+ NewExpertConstructor = this._editableExpert;
+ newExpertOptions = this._editableExpertOptions
|| {};
+ } else {
+ NewExpertConstructor = this._staticExpert;
+ newExpertOptions = this._staticExpertOptions ||
{};
+ }
+
+ if( !this._currentExpert // first call
+ || this._currentExpert.constructor !==
NewExpertConstructor
+ ) {
+ var rawValue = null;
+
+ if( this._currentExpert ) {
+ rawValue =
this._currentExpert.rawValue();
+
+ // Destroy old expert which was
responsible during previous state:
+ this._currentExpert.destroy();
+ this.$viewPort.empty();
+ }
+
+ // Instantiate new expert, responsible during
current state:
+ this._currentExpert = new NewExpertConstructor(
+ this.$viewPort,
+ this._viewState,
+ this._viewNotifier,
+ newExpertOptions
+ );
+ this._currentExpert.rawValue( rawValue );
+
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * @see jQuery.valueview.Expert.destroy
+ */
+ destroy: function() {
+ this.$viewPort = null;
+ this._viewState = null;
+ },
+
+ /**
+ * @see jQuery.valueview.Expert.parser
+ */
+ parser: function() {
+ return this._currentExpert.parser();
+ },
+
+ /**
+ * @see jQuery.valueview.Expert._getRawValue
+ */
+ _getRawValue: function() {
+ return this._currentExpert.rawValue();
+ },
+
+ /**
+ * @see jQuery.valueview.Expert._setRawValue
+ */
+ _setRawValue: function( rawValue ) {
+ return this._currentExpert.rawValue( rawValue );
+ },
+
+ /**
+ * @see jQuery.valueview.Expert.rawValueCompare
+ */
+ rawValueCompare: function( rawValue ) {
+ return this._currentExpert.rawValueCompare( rawValue );
+ },
+
+ /**
+ * @see jQuery.valueview.Expert.rawValueCompare
+ */
+ draw: function() {
+ if( !this._updateExpert() ) {
+ // Current expert still the right one, no
update, re-draw current expert.
+ this._currentExpert.draw();
+ }
+ },
+
+ /**
+ * @see jQuery.valueview.Expert.focus
+ */
+ focus: function() {
+ this._currentExpert.focus();
+ },
+
+ /**
+ * @see jQuery.valueview.Expert.blur
+ */
+ blur: function() {
+ this._currentExpert.blur();
+ }
+ } );
+
+}( dataValues, valueParsers, jQuery, jQuery.valueview ) );
diff --git
a/ValueView/resources/jquery.valueview/valueview.experts/experts.CommonsMediaType.js
b/ValueView/resources/jquery.valueview/valueview.experts/experts.CommonsMediaType.js
new file mode 100644
index 0000000..7c70e3d
--- /dev/null
+++
b/ValueView/resources/jquery.valueview/valueview.experts/experts.CommonsMediaType.js
@@ -0,0 +1,76 @@
+/**
+ * @file
+ * @ingroup ValueView
+ * @licence GNU GPL v2+
+ * @author Daniel Werner < [email protected] >
+ */
+( function( dv, vp, $, vv, wikiUrlencode ) {
+ 'use strict';
+
+ /**
+ * Returns an url to a certain file on commons.
+ *
+ * @param {string} file
+ * @returns string
+ */
+ function commonsUrl( file ) {
+ return location.protocol + '//commons.wikimedia.org/wiki/File:'
+ wikiUrlencode( file );
+ }
+
+ var PARENT = vv.BifidExpert,
+ editableExpert = vv.experts.SuggestedStringValue;
+
+ /**
+ * Valueview expert for adding specialized handling for CommonsMedia
data type. Without this
+ * more specialized expert, the StringValue expert would be used since
the CommonsMedia data
+ * type is using the String data value type.
+ * This expert is based on the StringValue expert but will add a
dropdown for choosing commons
+ * media sources. It will also display the value as a link to commons.
+ *
+ * @since 0.1
+ *
+ * @constructor
+ * @extends jQuery.valueview.experts.StringValue
+ */
+ vv.experts.CommonsMediaType = vv.expert( 'commonsmediatype', PARENT, {
+ /**
+ * @see jQuery.valueview.BifidExpert._editableExpert
+ */
+ _editableExpert: editableExpert,
+
+ /**
+ * @see jQuery.valueview.BifidExpert._editableExpertOptions
+ */
+ _editableExpertOptions: {
+ suggesterOptions: {
+ ajax: {
+ url: location.protocol +
'//commons.wikimedia.org/w/api.php',
+ params: {
+ action: 'opensearch',
+ namespace: 6
+ }
+ },
+ replace: [/^File:/, '']
+ }
+ },
+
+ /**
+ * @see jQuery.valueview.BifidExpert._staticExpert
+ */
+ _staticExpert: vv.experts.StaticDom,
+
+ /**
+ * @see jQuery.valueview.BifidExpert._staticExpertOptions
+ */
+ _staticExpertOptions: {
+ domBuilder: function( currentRawValue, viewState ) {
+ return $( '<a/>', {
+ text: currentRawValue,
+ href: commonsUrl( currentRawValue )
+ } );
+ },
+ baseExpert: editableExpert
+ }
+ } );
+
+}( dataValues, valueParsers, jQuery, jQuery.valueview, mw.util.wikiUrlencode )
);
diff --git
a/ValueView/resources/jquery.valueview/valueview.experts/experts.StaticDom.js
b/ValueView/resources/jquery.valueview/valueview.experts/experts.StaticDom.js
new file mode 100644
index 0000000..14e6399
--- /dev/null
+++
b/ValueView/resources/jquery.valueview/valueview.experts/experts.StaticDom.js
@@ -0,0 +1,96 @@
+/**
+ * @file
+ * @ingroup ValueView
+ * @licence GNU GPL v2+
+ * @author Daniel Werner < [email protected] >
+ */
+( function( $, vv ) {
+ 'use strict'
+
+ var PARENT = vv.Expert;
+
+ /**
+ * Valueview expert which will display its current value based on an
injected callback which
+ * is responsible for returning the DOM to be drawed. The DOM should be
static since this
+ * expert has no further logic required for handling interactive values.
+ *
+ * NOTE: This expert is useful when used as the static part of a
BifidExpert. It can be used to
+ * display the value in some specialized form, e.g. as a link or
formatted text or both mixed.
+ *
+ * @since 0.1
+ *
+ * @constructor
+ * @extends jQuery.valueview.Expert
+ *
+ * @option domBuilder {Function} A callback function called whenever
the DOM for displaying the
+ * current raw value is required. First parameter of the
callback is the current raw
+ * value of the expert, second parameter is the expert's
related ViewState object.
+ *
+ * @option baseExpert {Function} Constructor of an expert whose
"parser" and "rawValueCompare"
+ * functions will be borrowed. This is required because this
expert doesn't need to
+ * know what kind of values it handles.
+ *
+ * TODO: the "baseExpert" function is conceptually not that nice. It is
required because the
+ * a static DOM expert doesn't need to know what kind of values it
handles.
+ */
+ vv.experts.StaticDom = vv.expert( 'staticdom', PARENT, {
+ /**
+ * Current value.
+ * @type {*}
+ */
+ value: null,
+
+ /**
+ * @see jQuery.valueview.Expert.destroy
+ */
+ destroy: function() {
+ this._value = null;
+ PARENT.prototype.destroy.call( this );
+ },
+
+ /**
+ * Returns a parser suitable for parsing the raw value returned
by rawValue().
+ *
+ * @since 0.1
+ * @abstract
+ *
+ * @return valueParsers.Parser
+ */
+ parser: function() {
+ return this._options.baseExpert.prototype.parser.call(
this );
+ },
+
+ /**
+ * @see jQuery.valueview.Expert.destroy
+ */
+ _getRawValue: function() {
+ return this._value;
+ },
+
+ /**
+ * @see jQuery.valueview.Expert.destroy
+ */
+ _setRawValue: function( rawValue ) {
+ // TODO: this should probably also make use of the
"baseExpert" since there is no
+ // handling of the value at all here.
+ this._value = rawValue;
+ },
+
+ /**
+ * @see jQuery.valueview.Expert.rawValueCompare
+ */
+ rawValueCompare: function( value1, value2 ) {
+ return
this._options.baseExpert.prototype.rawValueCompare.apply( this, arguments );
+ },
+
+ /**
+ * @see jQuery.valueview.Expert.draw
+ */
+ draw: function() {
+ // Build DOM as specified by callback:
+ var $customDom = this._options.domBuilder(
this.rawValue(), this._viewState );
+ this.$viewPort.empty().append( $customDom );
+ }
+ } );
+
+}( jQuery, jQuery.valueview ) );
diff --git
a/ValueView/resources/jquery.valueview/valueview.experts/experts.SuggestedStringValue.js
b/ValueView/resources/jquery.valueview/valueview.experts/experts.SuggestedStringValue.js
new file mode 100644
index 0000000..d77604a
--- /dev/null
+++
b/ValueView/resources/jquery.valueview/valueview.experts/experts.SuggestedStringValue.js
@@ -0,0 +1,66 @@
+/**
+ * @file
+ * @ingroup ValueView
+ * @licence GNU GPL v2+
+ * @author Daniel Werner < [email protected] >
+ */
+( function( dv, vp, $, vv ) {
+ 'use strict';
+
+ var PARENT = vv.experts.StringValue;
+
+ /**
+ * Valueview expert based on StringValue expert but with a jQuery
suggester loaded for offering
+ * the user auto compleation features.
+ *
+ * @since 0.1
+ *
+ * @constructor
+ * @extends jQuery.valueview.experts.StringValue
+ *
+ * TODO: Implement this as an "extension" for the StringValue expert.
This could be done by
+ * adding a system for extensions which get initialized in addition to
a specific expert.
+ * Those extensions would also require registration, this should
probably be done by introducing
+ * a more complex format for registering an expert plus extensions to
an expert factory.
+ */
+ vv.experts.SuggestedStringValue = vv.expert( 'suggestedstringvalue',
PARENT, {
+ /**
+ * @see Query.valueview.experts.StringValue._init
+ */
+ _init: function() {
+ PARENT.prototype._init.call( this );
+
+ var notifier = this._viewNotifier,
+ $input = this.$input;
+
+ // Initialize Commons Media suggestion dropdown on top
of string input field:
+ $input.suggester( this._options.suggesterOptions );
+
+ // Since we're using the input auto expand, we have to
update the position of the
+ // dropdown whenever the input box expands vertically:
+ $input.eachchange( function( event, oldValue ) {
+ // TODO/OPTIMIZE: only reposition when
necessary, i.e. when expanding vertically
+ $input.data( 'suggester' ).repositionMenu();
+ } );
+
+ $input.on( 'suggesterresponse suggesterclose',
function( event, response ) {
+ notifier.notify( 'change' ); // here in
addition to 'eachchange' from StringValue expert
+ $input.data( 'AutoExpandInput' ).expand();
+
+ } );
+ },
+
+ /**
+ * @see Query.valueview.experts.StringValue.draw
+ */
+ draw: function() {
+ PARENT.prototype.draw.call( this );
+
+ // Make sure suggester is closed in non-edit mode:
+ if( !this._viewState.isInEditMode() ) {
+ this.$input.data( 'suggester' ).close();
+ }
+ }
+ } );
+
+}( dataValues, valueParsers, jQuery, jQuery.valueview ) );
diff --git a/ValueView/resources/mw.ext.valueView.js
b/ValueView/resources/mw.ext.valueView.js
index b223d0d..6153977 100644
--- a/ValueView/resources/mw.ext.valueView.js
+++ b/ValueView/resources/mw.ext.valueView.js
@@ -20,6 +20,11 @@
vv.experts.StringValue
);
+ expertProvider.registerExpert(
+ dt.getDataType( 'commonsMedia' ),
+ vv.experts.CommonsMediaType
+ );
+
/**
* Object representing the MeidaWiki "ValueView" extension.
*
--
To view, visit https://gerrit.wikimedia.org/r/57738
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ibf778f2ab544ec51f8f9574eb32aea82a5707caf
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/DataValues
Gerrit-Branch: master
Gerrit-Owner: Daniel Werner <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits