jenkins-bot has submitted this change and it was merged.
Change subject: Move flow( 'loadReplyForm' ) to base/action.js
......................................................................
Move flow( 'loadReplyForm' ) to base/action.js
Removes topic/post's own loadReplyForm methods, they can inherit parent's
Change-Id: Iee67765d60851deb62e4ce6b87b7869eedae224b
---
M modules/base/action.js
M modules/base/ui-functions.js
M modules/discussion/post.js
M modules/discussion/styles/nojs.less
M modules/discussion/styles/post.less
M modules/discussion/styles/topic.less
M modules/discussion/topic.js
M templates/post.html.php
M templates/topic.html.php
9 files changed, 192 insertions(+), 219 deletions(-)
Approvals:
EBernhardson: Looks good to me, approved
jenkins-bot: Verified
diff --git a/modules/base/action.js b/modules/base/action.js
index ae4941b..0c21481 100644
--- a/modules/base/action.js
+++ b/modules/base/action.js
@@ -23,26 +23,43 @@
};
/**
+ * HTML of the cancel link (well, jQuery node with the html of the link)
+ *
+ * @returns {jQuery}
+ */
+ mw.flow.action.prototype.cancelLink = function () {
+ return $(
+ '<a href="#" class="flow-cancel-link mw-ui-button
mw-ui-quiet">' +
+ mw.msg( 'flow-cancel' ) +
+ '</a>' +
+ // add some whitespace to separate from what's next ;)
+ ' '
+ );
+ };
+
+ /**
* HTML of the edit form (well, jQuery node with the html of the edit
form)
*
* @returns {jQuery}
*/
mw.flow.action.prototype.editForm = function () {
- return $(
+ var $form = $(
'<form class="flow-edit-form">' +
'<textarea class="mw-ui-input
flow-edit-content"></textarea>' +
'<div class="flow-form-controls
flow-edit-controls">' +
- '<a href="#" class="flow-cancel-link
mw-ui-button mw-ui-quiet">' +
- mw.msg( 'flow-cancel' ) +
- '</a>' +
+ // cancel link will be added here
'<input type="submit"
class="mw-ui-button mw-ui-constructive flow-edit-submit" value="' + mw.msg(
'flow-edit-' + this.object.type + '-submit' ) + '">' +
'</div>' +
'</form>'
);
+
+ this.cancelLink().prependTo( $form.find( '.flow-form-controls'
) );
+
+ return $form;
};
/**
- * Builds the edit form, using flow( setupEditForm ).
+ * Creates an edit form.
*
* @param {object} data this.prepareResult return value
* @param {function} [loadFunction] callback to be executed when form
is loaded
@@ -53,32 +70,34 @@
}
// build form DOM & attach to content
- var $postForm = this.editForm();
- $postForm.appendTo( this.object.$container );
+ var $form = this.editForm();
+ $form.appendTo( this.object.$container );
// add class to identify this form as being active
this.object.$container.addClass( 'flow-edit-form-active' );
// bind click on cancel, which should destroy this form
- $postForm.find( '.flow-cancel-link' ).on(
'click.mw-flow-discussion', $.proxy( function ( event ) {
+ $form.find( '.flow-cancel-link' ).on(
'click.mw-flow-discussion', $.proxy( function ( event ) {
event.preventDefault();
- $postForm.slideUp( 'fast', $.proxy(
this.destroyEditForm, this ) );
+ $form.slideUp( 'fast', $.proxy( this.destroyEditForm,
this ) );
}, this ) );
// setup preview
- $postForm.flow( 'setupPreview' );
+ $form.flow( 'setupPreview' );
// setup submission callback
- $postForm.flow( 'setupFormHandler',
+ $form.flow( 'setupFormHandler',
'.flow-edit-submit',
$.proxy( this.submitFunction, this, data ),
$.proxy( this.loadParametersCallback, this ),
$.proxy( this.validateCallback, this ),
- $.proxy( this.promiseCallback, this )
+ $.proxy( function ( deferred ) {
+ deferred.done( $.proxy( this.destroyEditForm,
this ) );
+ }, this )
);
// setup disabler (disables submit button until content is
entered)
- $postForm.flow( 'setupEmptyDisabler',
+ $form.flow( 'setupEmptyDisabler',
['.flow-edit-content'],
'.flow-edit-submit'
);
@@ -87,9 +106,8 @@
* Setting focus inside an event that grants focus (like
* clicking the edit icon), is tricky. This is a workaround.
*/
-
- setTimeout( $.proxy( function( $postForm, data, loadFunction ) {
- var $textarea = $postForm.find( 'textarea' ),
+ setTimeout( $.proxy( function( $form, data, loadFunction ) {
+ var $textarea = $form.find( 'textarea' ),
initialContent = this.initialContent( data );
mw.flow.editor
@@ -99,14 +117,14 @@
loadFunction,
// Then scroll to the form (after
callback to make sure we have the right height)
function () {
-
$postForm.conditionalScrollIntoView().queue( function () {
+
$form.conditionalScrollIntoView().queue( function () {
mw.flow.editor.focus(
$textarea );
mw.flow.editor.moveCursorToEnd( $textarea );
$( this ).dequeue();
} );
}
);
- }, this, $postForm, data, loadFunction ), 0 );
+ }, this, $form, data, loadFunction ), 0 );
};
/**
@@ -120,13 +138,146 @@
};
/**
+ * Creates a reply form.
+ *
+ * Unlike edit forms, reply forms already exit in HTML, we just have
+ * to "activate" some JS magic.
+ *
+ * @param {function} [loadFunction] callback to be executed when form
is loaded
+ */
+ mw.flow.action.prototype.loadReplyForm = function ( loadFunction ) {
+ if ( this.object.$container.hasClass( 'flow-reply-form-active'
) ) {
+ return;
+ }
+
+ var $form = this.$form.find( 'form' );
+
+ // add class to identify this form as being active
+ this.object.$container.addClass( 'flow-reply-form-active' );
+ this.$form.addClass( 'flow-reply-form-active' );
+
+ // hide topic reply form
+ // can't do this in CSS, since selectors traveling upwards
don't really exist ;)
+ this.object.$container.closest( '.flow-topic-container' ).find(
'.flow-topic-reply-container' ).hide();
+ // make sure to show this form, though
+ this.$form.show();
+
+ // add cancel link
+ this.cancelLink()
+ .on( 'click.mw-flow-discussion', $.proxy( function (
event ) {
+ event.preventDefault();
+ $form.slideUp( 'fast', $.proxy(
this.destroyReplyForm, this ) );
+ }, this ) )
+ .prependTo( $form.find( '.flow-form-controls' ) );
+
+ // setup preview
+ $form.flow( 'setupPreview' );
+
+ // setup submission callback
+ $form.flow( 'setupFormHandler',
+ '.flow-reply-submit',
+ $.proxy( this.submitFunction, this ),
+ $.proxy( this.loadParametersCallback, this, $form ),
+ $.proxy( this.validateCallback, this ),
+ $.proxy( function ( deferred ) {
+ deferred.done( $.proxy( this.destroyReplyForm,
this ) );
+ }, this )
+ );
+
+ // setup disabler (disables submit button until content is
entered)
+ $form.flow( 'setupEmptyDisabler',
+ ['.flow-reply-content'],
+ '.flow-reply-submit'
+ );
+
+ /*
+ * Setting focus inside an event that grants focus (like
+ * clicking the reply button), is tricky. This is a workaround.
+ */
+ setTimeout( $.proxy( function( $form, loadFunction ) {
+ var $textarea = $form.find( 'textarea' ),
+ initialContent = this.initialContent();
+
+ $textarea
+ .removeClass( 'flow-reply-box-closed' )
+ // Override textarea height; doesn't need to be
too large initially,
+ // it'll auto-expand
+ .attr( 'rows', '6' )
+ // Textarea will auto-expand + textarea padding
will cause the
+ // resize grabber to be positioned badly (in
FF) so get rid of it
+ .css( 'resize', 'none' );
+
+ mw.flow.editor
+ .load( $textarea, initialContent.content,
initialContent.format )
+ .done(
+ // Run the callback function
+ loadFunction,
+ // Then scroll to the form (after
callback to make sure we have the right height)
+ function () {
+
$form.conditionalScrollIntoView().queue( function () {
+ mw.flow.editor.focus(
$textarea );
+
mw.flow.editor.moveCursorToEnd( $textarea );
+ $( this ).dequeue();
+ } );
+ }
+ );
+ }, this, $form, loadFunction ), 0 );
+ };
+
+ /**
+ * Hides the reply form & restores content.
+ */
+ mw.flow.action.prototype.destroyReplyForm = function () {
+ var $form = this.$form.find( 'form' ),
+ $textarea = $form.find( 'textarea' );
+
+ this.object.$container.removeClass( 'flow-reply-form-active' );
+ this.$form.removeClass( 'flow-reply-form-active' );
+
+ mw.flow.editor.destroy( $textarea );
+ $form.flow( 'hidePreview' );
+
+ // when closed, display topic reply form again
+ // can't do this in CSS, since selectors traveling upwards
don't really exist ;)
+ this.object.$container.closest( '.flow-topic-container' ).find(
'.flow-topic-reply-container' ).show();
+
+ /*
+ * Because we're not entirely killing the forms, we have to
clean up
+ * after cancelling a form (e.g. reply-forms may be re-used
across posts
+ * - when max threading depth has been reached)
+ *
+ * After submitting the reply, kill the events that were bound
to the
+ * submit button via setupEmptyDisabler and setupFormHandler.
+ */
+ $form.find( '.flow-reply-submit' ).off();
+ $form.find( '.flow-cancel-link, .flow-content-preview,
.flow-preview-submit, .flow-error' ).remove();
+
+ // when hidden via slideUp, some inline CSS is added to keep the
+ // elements hidden, but we want it in it's original state
(where CSS
+ // scoping :not(.flow-reply-form-active) will make the form
stay hidden)
+ $form.css( 'display', '' );
+ };
+
+ /**
+ * Submit function for flow( 'setupFormHandler' ).
+ *
+ * @param {object} data this.prepareResult return value
+ * @return {jQuery.Deferred}
+ */
+ mw.flow.action.prototype.submitFunction = function ( data ) {
+ // base action.js has no default submitFunction - will need
custom implementation
+ throw 'submitFunction not yet implemented';
+ };
+
+ /**
* Feeds parameters to flow( 'setupFormHandler' ).
*
+ * @param {jQuery} $form
* @return {array} Array with params, to be fed to validateCallback &
* submitFunction
*/
- mw.flow.action.prototype.loadParametersCallback = function () {
- var $textarea = this.object.$container.find(
'.flow-edit-content' ),
+ mw.flow.action.prototype.loadParametersCallback = function ( $form ) {
+ var $textarea = $form.find( 'textarea' ),
content = mw.flow.editor.getContent( $textarea );
return [ content ];
@@ -141,13 +292,6 @@
*/
mw.flow.action.prototype.validateCallback = function ( content ) {
return !!content;
- };
-
- /**
- * @param {jQuery.Deferred} deferred
- */
- mw.flow.action.prototype.promiseCallback = function ( deferred ) {
- deferred.done( $.proxy( this.destroyEditForm, this ) );
};
/**
diff --git a/modules/base/ui-functions.js b/modules/base/ui-functions.js
index e0e62c0..8ad14e3 100644
--- a/modules/base/ui-functions.js
+++ b/modules/base/ui-functions.js
@@ -79,150 +79,6 @@
},
/**
- * Sets up a reply form.
- *
- * Unlike edit forms, reply forms already exit in HTML,
we just have
- * to "activate" some JS magic.
- *
- * @param {string} type The type of
edit form (single word)
- * @param {string|object} initialContent The content
to pre-fill.
- * An object, with the keys 'content' and 'format'. Or
a plain string of wikitext.
- * @param {function} submitFunction Function to
call in order to submit the form.
- * One parameter, the content.
- * @param {function} loadFunction Function to
call once the form is loaded.
- * @return {Promise} A promise
that will be resolved or rejected
- * when the form submission has returned.
- */
- 'loadReplyForm' : function( type, initialContent,
submitFunction, loadFunction ) {
- var $formContainer = $( this ),
- $form = $formContainer.find( 'form' ),
- $textarea = $formContainer.find(
'textarea' ),
- deferredObject = $.Deferred();
-
- if ( $formContainer.hasClass(
'flow-form-active' ) ) {
- // This is a bit yucky, but should
behave correctly in most cases
- return deferredObject.promise();
- }
-
- // add class to identify this form as being
active
- $formContainer.addClass( 'flow-form-active' );
-
- // hide topic reply form
- $formContainer.closest( '.flow-topic-container'
).find( '.flow-topic-reply-container' ).hide();
-
- // show this form
- $formContainer.show();
-
- // add cancel link
- $( '<a />' )
- .attr( 'href', '#' )
- .addClass( 'flow-cancel-link
mw-ui-button mw-ui-quiet' )
- .text( mw.msg( 'flow-cancel' ) )
- .on( 'click.mw-flow-discussion',
function ( e ) {
- e.preventDefault();
-
- mw.flow.editor.destroy(
$textarea );
- $form.flow( 'hidePreview' );
-
- // when closed, display topic
reply form again
- $formContainer
- .closest(
'.flow-topic-container' )
- .find(
'.flow-topic-reply-container' )
- .show();
-
- /*
- * Because we're not entirely
killing the forms, we have
- * to clean up after cancelling
a form (e.g. reply-forms
- * may be re-used across posts
- when max threading
- * depth has been reached)
- *
- * After submitting the reply,
kill the events that were
- * bound to the submit button
via setupEmptyDisabler and
- * setupFormHandler.
- */
- $formContainer.find(
'.flow-'+type+'-reply-submit' ).off();
- $formContainer.removeClass(
'flow-form-active' );
- $( this ).remove();
- $formContainer.find(
'.flow-content-preview, .flow-preview-submit' ).remove();
- } )
- .after( ' ' )
- .prependTo( $formContainer.find(
'.flow-form-controls') );
-
- // setup preview
- $form.flow( 'setupPreview' );
-
- // setup submission callback
- $formContainer.flow( 'setupFormHandler',
- '.flow-'+type+'-reply-submit',
- submitFunction,
- function () {
- var content =
mw.flow.editor.getContent( $formContainer.find( '.flow-'+type+'-reply-content'
) );
- return [ content ];
- },
- function ( content ) {
- return content;
- },
- function ( promise ) {
- promise
- .done( function () {
-
deferredObject.resolve.apply( $formContainer, arguments );
- } )
- .fail( function() {
-
deferredObject.reject.apply( $formContainer, arguments );
- } );
- }
- );
-
- // setup disabler (disables submit button until
content is entered)
- $formContainer.flow( 'setupEmptyDisabler',
- ['.flow-'+type+'-reply-content'],
- '.flow-'+type+'-reply-submit'
- );
-
- if ( typeof initialContent !== 'object' ) {
- initialContent = {
- 'content' : initialContent,
- 'format' : 'wikitext'
- };
- }
-
- /*
- * Setting focus inside an event that grants
focus (like
- * clicking the reply button), is tricky. This
is a workaround.
- */
- setTimeout( $.proxy( function( $formContainer,
initialContent, loadFunction ) {
- var $textarea = $formContainer.find(
'textarea' );
-
- $textarea
- .removeClass(
'flow-reply-box-closed' )
- // Override textarea height;
doesn't need to be too large initially,
- // it'll auto-expand
- .attr( 'rows', '6' )
- // Textarea will auto-expand +
textarea padding will cause the
- // resize grabber to be
positioned badly (in FF) so get rid of it
- .css( 'resize', 'none' );
-
- mw.flow.editor
- .load( $textarea,
initialContent.content, initialContent.format )
- .done(
- // Run the callback
function
- loadFunction,
- // Then scroll to the
form (after callback to make sure we have the right height)
- function () {
-
$formContainer.conditionalScrollIntoView().queue( function () {
-
mw.flow.editor.focus( $textarea );
-
mw.flow.editor.moveCursorToEnd( $textarea );
- $( this
).dequeue();
- } );
- }
- );
-
- }, this, $formContainer, initialContent,
loadFunction ), 0 );
-
- return deferredObject.promise();
- },
-
- /**
* @param {string} submitSelector jQuery selector
string to capture submit button
* @param {function} submitFunction Function to execute
when submitting form
* @param {function} loadParametersCallback Function to
load parameters to be submitted
@@ -559,7 +415,10 @@
'type': 'submit',
'value': mw.msg( 'flow-preview' ),
'class': 'mw-ui-button
flow-preview-submit'
- } ).insertAfter( $form.find(
'.flow-cancel-link' ) );
+ } )
+ // add some whitespace to separate from what's
next ;)
+ .after( ' ' )
+ .insertAfter( $form.find( '.flow-cancel-link' )
);
// allow chaining
return this;
diff --git a/modules/discussion/post.js b/modules/discussion/post.js
index 4f20d08..0cdd31d 100644
--- a/modules/discussion/post.js
+++ b/modules/discussion/post.js
@@ -322,21 +322,6 @@
};
/**
- * Builds the reply form.
- *
- * @param {function} [loadFunction] callback to be executed when form
is loaded
- */
- mw.flow.action.post.reply.prototype.loadReplyForm = function (
loadFunction ) {
- this.$form.flow(
- 'loadReplyForm',
- this.object.type,
- this.initialContent(),
- $.proxy( this.submitFunction, this ),
- loadFunction
- );
- };
-
- /**
* Submit function for flow( 'setupFormHandler' ).
* Arguments passed to this function are the return value of
* loadParametersCallback
diff --git a/modules/discussion/styles/nojs.less
b/modules/discussion/styles/nojs.less
index 450e66f..c3bc761 100644
--- a/modules/discussion/styles/nojs.less
+++ b/modules/discussion/styles/nojs.less
@@ -50,7 +50,7 @@
}
// don't shrink reply form (it can't auto-expand)
- .flow-topic-reply-content {
+ .flow-reply-content {
height: auto;
}
diff --git a/modules/discussion/styles/post.less
b/modules/discussion/styles/post.less
index 73d3fef..5c9d349 100644
--- a/modules/discussion/styles/post.less
+++ b/modules/discussion/styles/post.less
@@ -218,7 +218,7 @@
padding: 10px 0 10px 22px;
display: none;
- &.flow-form-active {
+ &.flow-reply-form-active {
display: block;
}
}
diff --git a/modules/discussion/styles/topic.less
b/modules/discussion/styles/topic.less
index 1a55aa5..f38d5e5 100644
--- a/modules/discussion/styles/topic.less
+++ b/modules/discussion/styles/topic.less
@@ -270,7 +270,7 @@
display: none;
}
- &.flow-form-active {
+ &.flow-new-form-active {
.flow-newtopic-step2 {
display: block;
}
@@ -293,16 +293,16 @@
// hide controls when form is inactive
// class is added via JS, so controls are always visible for non-JS
- &.flow-form-active {
+ &.flow-reply-form-active {
.flow-form-controls {
display: block;
}
}
- &:not(.flow-form-active) {
- // Make the "comment on topic" textarea look like the "start a
new topic"
- // input field.
- .flow-topic-reply-content {
+ // Make the "comment on topic" textarea look like the "start a new
topic"
+ // input field.
+ &:not(.flow-reply-form-active) {
+ .flow-reply-content {
height: 34px;
}
diff --git a/modules/discussion/topic.js b/modules/discussion/topic.js
index cb866de..d96b4ca 100644
--- a/modules/discussion/topic.js
+++ b/modules/discussion/topic.js
@@ -385,7 +385,7 @@
this.$form = this.object.$container.find(
'.flow-topic-reply-container' );
// Overload focus in textarea, triggering full reply form
- this.$form.find( '.flow-topic-reply-content' ).on(
'focus.mw-flow-discussion', $.proxy( this.reply, this ) );
+ this.$form.find( '.flow-reply-content' ).on(
'focus.mw-flow-discussion', $.proxy( this.reply, this ) );
};
// extend edit action from "shared functionality" mw.flow.action class
@@ -403,21 +403,6 @@
// load the form
this.loadReplyForm();
- };
-
- /**
- * Builds the reply form.
- *
- * @param {function} [loadFunction] callback to be executed when form
is loaded
- */
- mw.flow.action.topic.reply.prototype.loadReplyForm = function (
loadFunction ) {
- this.$form.flow(
- 'loadReplyForm',
- this.object.type,
- this.initialContent(),
- $.proxy( this.submitFunction, this ),
- loadFunction
- );
};
/**
@@ -482,12 +467,12 @@
event.preventDefault();
// don't re-bind if form is already active
- if ( this.$form.hasClass( 'flow-form-active' ) ) {
+ if ( this.$form.hasClass( 'flow-new-form-active' ) ) {
return;
}
// mark form as active
- this.$form.addClass( 'flow-form-active' );
+ this.$form.addClass( 'flow-new-form-active' );
// load the form
this.loadNewForm();
@@ -560,13 +545,13 @@
$( '.flow-newtopic-submit', this.$form ).off();
// cleanup what's been added via JS
- this.$form.removeClass( 'flow-form-active' );
+ this.$form.removeClass( 'flow-new-form-active'
);
this.$form.find( '.flow-cancel-link,
.flow-content-preview, .flow-preview-submit' ).remove();
this.$form.find( '.flow-error' ).remove();
// slideUp adds some inline CSS to keep the
elements hidden,
// but we want it in it's original state (where
CSS scoping
- // :not(.flow-form-active) will make the form
stay hidden)
+ // :not(.flow-new-form-active) will make the
form stay hidden)
this.$form.find( '.flow-newtopic-step2' ).css(
'display', '' );
}, this ) );
};
diff --git a/templates/post.html.php b/templates/post.html.php
index 2dd9cdf..b471f70 100644
--- a/templates/post.html.php
+++ b/templates/post.html.php
@@ -39,7 +39,7 @@
Html::textarea( $block->getName() . '_content', '', array(
'placeholder' => $placeHolder,
'title' => $placeHolder,
- 'class' => 'flow-post-reply-content mw-ui-input',
+ 'class' => 'flow-reply-content mw-ui-input',
'rows' => '10',
) ) .
// NOTE: cancel button will be added via JS, makes no sense in
non-JS context
@@ -50,7 +50,7 @@
Html::element( 'input', array(
'type' => 'submit',
'value' => $postView->replySubmit(),
- 'class' => 'mw-ui-button mw-ui-constructive
flow-post-reply-submit',
+ 'class' => 'mw-ui-button mw-ui-constructive
flow-reply-submit',
) ) .
Html::element( 'div', array( 'class' => 'clear' ) ) .
Html::closeElement( 'div' ) .
diff --git a/templates/topic.html.php b/templates/topic.html.php
index df1d9c5..953def6 100644
--- a/templates/topic.html.php
+++ b/templates/topic.html.php
@@ -39,7 +39,7 @@
) ) .
Html::textarea( $block->getName() .
'_topic-reply-content', '', array(
'placeholder' => wfMessage(
'flow-reply-topic-placeholder', $user->getName(), $title )->text(),
- 'class' => 'mw-ui-input
flow-topic-reply-content',
+ 'class' => 'mw-ui-input flow-reply-content',
'rows' => '10',
) ) .
'<div class="flow-form-controls">' .
@@ -49,7 +49,7 @@
Html::element( 'input', array(
'type' => 'submit',
'value' => wfMessage(
'flow-reply-submit', $this->getCreatorText( $root ) ),
- 'class' => 'mw-ui-button
mw-ui-constructive flow-topic-reply-submit',
+ 'class' => 'mw-ui-button
mw-ui-constructive flow-reply-submit',
) ) .
Html::element( 'div', array( 'class' => 'clear'
) ) .
Html::closeElement( 'div' ) .
--
To view, visit https://gerrit.wikimedia.org/r/108634
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Iee67765d60851deb62e4ce6b87b7869eedae224b
Gerrit-PatchSet: 7
Gerrit-Project: mediawiki/extensions/Flow
Gerrit-Branch: master
Gerrit-Owner: Matthias Mullie <[email protected]>
Gerrit-Reviewer: EBernhardson <[email protected]>
Gerrit-Reviewer: Matthias Mullie <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits