EBernhardson (WMF) has submitted this change and it was merged.
Change subject: edit-post action for Topic block
......................................................................
edit-post action for Topic block
Includes some refactoring of Parsoid, and a few other unrelated changes.
Change-Id: Ie62ff67ae09ec131ae49acce3ffe779311203842
---
M Flow.i18n.php
M Flow.php
M includes/Block/Topic.php
M includes/Block/TopicList.php
M includes/Model/PostRevision.php
M includes/Model/UUID.php
M includes/Model/Workflow.php
A includes/ParsoidUtils.php
M includes/Templating.php
M includes/UrlGenerator.php
M includes/api/ApiQueryFlow.php
M modules/base/ext.flow.base.js
M modules/discussion/base.css
M modules/discussion/discussion.js
A templates/edit-post.html.php
M templates/post.html.php
M templates/topic.html.php
17 files changed, 502 insertions(+), 117 deletions(-)
Approvals:
EBernhardson (WMF): Verified; Looks good to me, approved
diff --git a/Flow.i18n.php b/Flow.i18n.php
index 38844e0..2914ba7 100644
--- a/Flow.i18n.php
+++ b/Flow.i18n.php
@@ -29,7 +29,13 @@
'flow-reply-placeholder' => 'Click to reply to $1. Be nice!',
'flow-reply-submit' => 'Post Reply',
+ 'flow-edit-post-submit' => 'Submit changes',
+
+ 'flow-post-action-view' => 'Permalink',
+ 'flow-post-action-post-history' => 'Post history',
'flow-post-action-delete-post' => 'Delete post',
+ 'flow-post-action-edit-post' => 'Edit post',
+ 'flow-post-action-edit' => 'Edit',
'flow-post-action-restore-post' => 'Restore post',
'flow-topic-action-edit-title' => 'Edit Title',
diff --git a/Flow.php b/Flow.php
index 2ba0fee..10508c5 100755
--- a/Flow.php
+++ b/Flow.php
@@ -40,7 +40,7 @@
'descriptionmsg' => 'flow-desc',
);
-$dir = dirname( __FILE__ ) . '/';
+$dir = __DIR__ . '/';
$wgExtensionMessagesFiles['Flow'] = $dir . 'Flow.i18n.php';
// Classes fulfilling the mediawiki extension architecture
@@ -51,6 +51,7 @@
$wgAutoloadClasses['Pimple'] = $dir . 'vendor/Pimple.php';
$wgAutoloadClasses['Flow\Container'] = $dir . 'includes/Container.php';
$wgAutoloadClasses['Flow\DbFactory'] = $dir . 'includes/DbFactory.php';
+$wgAutoloadClasses['Flow\ParsoidUtils'] = $dir . 'includes/ParsoidUtils.php';
$wgAutoloadClasses['Flow\Templating'] = $dir . 'includes/Templating.php';
$wgAutoloadClasses['Flow\UrlGenerator'] = $dir . 'includes/UrlGenerator.php';
$wgAutoloadClasses['Flow\WorkflowLoader'] = $dir .
'includes/WorkflowLoader.php';
@@ -158,6 +159,7 @@
'flow-error-external',
'flow-error-external-multi',
'flow-edit-title-submit',
+ 'flow-edit-post-submit',
),
),
);
@@ -190,6 +192,6 @@
$wgFlowUseParsoid = false;
$wgFlowParsoidURL = 'http://localhost:8000';
-$wgFlowParsoidPrefix = '_wikitext';
+$wgFlowParsoidPrefix = 'localhost';
$wgFlowParsoidTimeout = 100;
diff --git a/includes/Block/Topic.php b/includes/Block/Topic.php
index 59f5a9b..66ddb02 100644
--- a/includes/Block/Topic.php
+++ b/includes/Block/Topic.php
@@ -8,6 +8,7 @@
use Flow\Data\ManagerGroup;
use Flow\Data\RootPostLoader;
use Flow\DbFactory;
+use Flow\ParsoidUtils;
use Flow\Templating;
use User;
@@ -17,8 +18,12 @@
protected $topicTitle;
protected $rootLoader;
protected $newRevision;
+ protected $requestedPost;
- protected $supportedActions = array( 'edit-title', 'reply',
'delete-topic', 'delete-post', 'restore-post' );
+ protected $supportedActions = array(
+ 'edit-post', 'delete-post', 'restore-post',
+ 'reply', 'delete-topic',
+ );
public function __construct( Workflow $workflow, ManagerGroup $storage,
$root ) {
parent::__construct( $workflow, $storage );
@@ -56,6 +61,10 @@
$this->validateRestorePost();
break;
+ case 'edit-post':
+ $this->validateEditPost();
+ break;
+
default:
throw new \MWException( "Unexpected action:
{$this->action}" );
}
@@ -80,7 +89,7 @@
if ( empty( $this->submitted['content'] ) ) {
$this->errors['content'] = wfMessage(
'flow-error-missing-content' );
} else {
- $this->parsedContent = $this->convertWikitextToHtml5(
$this->submitted['content'] );
+ $this->parsedContent =
ParsoidUtils::convertWikitextToHtml5( $this->submitted['content'],
$this->workflow->getArticleTitle() );
if ( empty( $this->parsedContent ) ) {
$this->errors['content'] = wfMessage(
'flow-error-parsoid-failure' );
}
@@ -153,45 +162,25 @@
}
}
- // @todo: I assume not only topic reply, but also TopicListBlock &
SummaryBlock's content need to be converted?
- protected function convertWikitextToHtml5( $wikitext ) {
- global $wgFlowUseParsoid;
-
- if ( $wgFlowUseParsoid ) {
- global $wgFlowParsoidURL, $wgFlowParsoidPrefix,
$wgFlowParsoidTimeout;
-
- $parsoidOutput = \Http::post(
- $wgFlowParsoidURL . '/' . $wgFlowParsoidPrefix
. '/',
- array(
- 'postData' => array(
- 'content' => $wikitext,
- 'format' => 'html',
- ),
- 'timeout' => $wgFlowParsoidTimeout
- )
- );
-
- // Strip out the Parsoid boilerplate
- $dom = new \DOMDocument();
- $dom->loadHTML( $parsoidOutput );
- $body = $dom->getElementsByTagName( 'body' )->item(0);
- $html = '';
-
- foreach( $body->childNodes as $child ) {
- $html .= $child->ownerDocument->saveXML( $child
);
- }
-
- return $html;
+ protected function validateEditPost() {
+ if ( empty( $this->submitted['postId'] ) ) {
+ $this->errors['edit-post'] = wfMessage(
'flow-no-post-provided' );
+ return;
+ }
+ if ( empty( $this->submitted['content'] ) ) {
+ $this->errors['content'] = wfMessage(
'flow-missing-post-content' );
} else {
- global $wgParser;
-
- $title = \Title::newFromText( 'Flow', NS_SPECIAL );
-
- $options = new \ParserOptions;
- $options->setTidy( true );
-
- $output = $wgParser->parse( $wikitext, $title, $options
);
- return $output->getText();
+ $this->parsedContent =
ParsoidUtils::convertWikitextToHtml5( $this->submitted['content'],
$this->workflow->getArticleTitle() );
+ if ( empty( $this->parsedContent ) ) {
+ $this->errors['content'] = wfMessage(
'flow-empty-parsoid-result' );
+ return;
+ }
+ }
+ $post = $this->loadRequestedPost( $this->submitted['postId'] );
+ if ( $post ) {
+ $this->newRevision = $post->newNextRevision(
$this->user, $this->parsedContent );
+ } else {
+ $this->errors['edit-post'] = wfMessage(
'flow-post-not-found' );
}
}
@@ -201,6 +190,7 @@
case 'delete-post':
case 'restore-post':
case 'edit-title':
+ case 'edit-post':
if ( $this->newRevision === null ) {
throw new \MWException( 'Attempt to save null
revision' );
}
@@ -241,35 +231,80 @@
}
public function render( Templating $templating, array $options, $return
= false ) {
- if ( $this->action === 'post-history' ) {
- if ( empty( $options['postId'] ) ) {
- var_dump( $this->getName() );
- var_dump( $options );
- throw new \Exception( 'No postId specified' );
- $history = array();
- } else {
- $history = $this->getHistory(
$options['postId'] );
- }
- return $templating->render(
"flow:post-history.html.php", array(
- 'block' => $this,
- 'topic' => $this->workflow,
- 'history' => $history,
- ), $return );
- } elseif ( $this->action === 'edit-title' ) {
+ $templating->getOutput()->addModules( 'ext.flow.discussion' );
+ switch( $this->action ) {
+ case 'post-history':
+ return $this->renderPostHistory( $templating, $options,
$return );
+
+ case 'edit-post':
+ return $this->renderEditPost( $templating, $options,
$return );
+
+ case 'edit-title':
return $templating->render( "flow:edit-title.html.php",
array(
'block' => $this,
- 'user' => $this->user,
'topic' => $this->workflow,
'topicTitle' => $this->loadTopicTitle(),
) );
+
+ default:
+ $root = $this->loadRootPost();
+
+ if ( isset( $options['postId'] ) ) {
+ $post = $root->findDescendant(
$options['postId'] );
+
+ return $templating->renderPost(
+ $post,
+ $this,
+ $return
+ );
+ } else {
+ return $templating->renderTopic(
+ $root,
+ $this,
+ $return
+ );
+ }
}
-
- $templating->getOutput()->addModules( 'ext.flow.base' );
-
- return $templating->renderTopic( $this, $this->workflow,
$this->loadRootPost(), $this->user );
}
- public function renderAPI ( array $options ) {
+ protected function renderPostHistory( Templating $templating, array
$options, $return = false ) {
+ if ( !isset( $options['postId'] ) ) {
+ throw new \Exception( 'No postId provided' );
+ }
+ return $templating->render( "flow:post-history.html.php", array(
+ 'block' => $this,
+ 'topic' => $this->workflow,
+ 'history' => $$this->getHistory( $options['postId'] ),
+ ), $return );
+ }
+
+ protected function renderEditPost( Templating $templating, array
$options, $return = false ) {
+ if ( !isset( $options['postId'] ) ) {
+ throw new \Exception( 'No postId provided' );
+ }
+ return $templating->render( "flow:edit-post.html.php", array(
+ 'block' => $this,
+ 'topic' => $this->workflow,
+ 'post' => $this->loadRequestedPost( $options['postId']
),
+ ), $return );
+ }
+
+ public function renderAPI( array $options ) {
+ if ( isset( $options['postId'] ) ) {
+ $rootPost = $this->loadRootPost();
+ $post = $rootPost->findDescendant( $options['postId'] );
+
+ if ( ! $post ) {
+ throw new MWException( "Requested post could
not be found" );
+ }
+
+ return $this->renderPostAPI( $post, $options );
+ } else {
+ return $this->renderTopicAPI( $options );
+ }
+ }
+
+ public function renderTopicAPI ( array $options ) {
$output = array();
$rootPost = $this->loadRootPost();
$topic = $this->workflow;
@@ -313,17 +348,21 @@
$output['post-deleted'] = 'post-deleted';
} else {
$output['content'] = array( '*' => $post->getContent()
);
+ $contentSource = ParsoidUtils::convertHtml5ToWikitext(
$post->getContent() );
+ $output['content-src'] = array( '*' => $contentSource );
$output['user'] = $post->getUserText();
}
- $children = array( '_element' => 'post' );
+ if ( ! isset( $options['no-children'] ) ) {
+ $children = array( '_element' => 'post' );
- foreach( $post->getChildren() as $child ) {
- $children[] = $this->renderPostAPI( $child, $options );
- }
+ foreach( $post->getChildren() as $child ) {
+ $children[] = $this->renderPostAPI( $child,
$options );
+ }
- if ( count($children) > 1 ) {
- $output['replies'] = $children;
+ if ( count($children) > 1 ) {
+ $output['replies'] = $children;
+ }
}
$postId = $post->getPostId()->getHex();
@@ -421,6 +460,24 @@
return $this->topicTitle;
}
+ protected function loadRequestedPost( $postId ) {
+ if ( !isset( $this->requestedPost[$postId] ) ) {
+ $found = $this->storage->find(
+ 'PostRevision',
+ array( 'tree_rev_descendant_id' => $postId ),
+ array( 'sort' => 'rev_id', 'order' => 'DESC',
'limit' => 1 )
+ );
+ if ( $found ) {
+ $this->requestedPost[$postId] = reset( $found );
+ } else {
+ // meh, signals that its not found, dont look
again
+ $this->requestedPost[$postId] = false;
+ }
+ }
+ // catches the === false and returns null as expected
+ return $this->requestedPost[$postId] ?: null;
+ }
+
// Somehow the template has to know which post the errors go with
public function getRepliedTo() {
return isset( $this->submitted['replyTo'] ) ?
$this->submitted['replyTo'] : null;
@@ -433,7 +490,7 @@
// The prefix used for form data
public function getName() {
- return 'topic_list';
+ return 'topic';
}
}
diff --git a/includes/Block/TopicList.php b/includes/Block/TopicList.php
index 9d302cb..142493f 100644
--- a/includes/Block/TopicList.php
+++ b/includes/Block/TopicList.php
@@ -66,7 +66,7 @@
'created-post-id' => $firstPost->getRevisionId(),
'render-function' => function($templating) use
($topicWorkflow, $firstPost, $topicPost, $storage, $user) {
$block = new TopicBlock( $topicWorkflow,
$storage, $topicPost );
- return $templating->renderTopic( $block,
$topicWorkflow, $topicPost, $user );
+ return $templating->renderTopic( $topicPost,
$block, $user );
},
);
diff --git a/includes/Model/PostRevision.php b/includes/Model/PostRevision.php
index 359aa46..e91da62 100644
--- a/includes/Model/PostRevision.php
+++ b/includes/Model/PostRevision.php
@@ -106,6 +106,25 @@
return $this->children;
}
+ public function findDescendant( $postId ) {
+ if ( ! $postId instanceof UUID ) {
+ $postId = UUID::create( $postId );
+ }
+
+ $stack = array( $this );
+ while( $stack ) {
+ $post = array_pop( $stack );
+ if ( $post->getPostId()->equals( $postId ) ) {
+ return $post;
+ }
+ foreach ( $post->getChildren() as $child ) {
+ $stack[] = $child;
+ }
+ }
+
+ throw new \Exception( 'Requested postId is not available within
post tree' );
+ }
+
/**
* Returns 1 if $this is newer than $rev, -1 is $rev is newer than
* $this, and 0 if created at same moment.
diff --git a/includes/Model/UUID.php b/includes/Model/UUID.php
index 2aee92c..38553de 100644
--- a/includes/Model/UUID.php
+++ b/includes/Model/UUID.php
@@ -66,4 +66,8 @@
return $array;
}
+
+ public function equals( UUID $other ) {
+ return $other->getBinary() === $this->getBinary();
+ }
}
diff --git a/includes/Model/Workflow.php b/includes/Model/Workflow.php
index c16efa2..3f79665 100644
--- a/includes/Model/Workflow.php
+++ b/includes/Model/Workflow.php
@@ -90,7 +90,7 @@
if ( $this->wiki !== wfWikiId() ) {
throw new \MWException( 'Interwiki not implemented' );
}
- return Title::newFromText( $this->titleText, $this->namespace );
+ return Title::makeTitleSafe( $this->namespace, $this->titleText
);
}
public function getId() { return $this->id; }
diff --git a/includes/ParsoidUtils.php b/includes/ParsoidUtils.php
new file mode 100644
index 0000000..3e4564c
--- /dev/null
+++ b/includes/ParsoidUtils.php
@@ -0,0 +1,67 @@
+<?php
+
+namespace Flow;
+
+abstract class ParsoidUtils {
+ public static function convertWikitextToHtml5( $wikitext, $title ) {
+ global $wgFlowUseParsoid;
+
+ if ( $wgFlowUseParsoid ) {
+ global $wgFlowParsoidURL, $wgFlowParsoidPrefix,
$wgFlowParsoidTimeout;
+
+ $parsoidOutput = \Http::post(
+ $wgFlowParsoidURL . '/_wikitext/' .
$title->getPrefixedUrl(),
+ array(
+ 'postData' => array(
+ 'content' => $wikitext,
+ 'format' => 'html',
+ ),
+ 'timeout' => $wgFlowParsoidTimeout
+ )
+ );
+
+ // Strip out the Parsoid boilerplate
+ $dom = new \DOMDocument();
+ $dom->loadHTML( $parsoidOutput );
+ $body = $dom->getElementsByTagName( 'body' )->item(0);
+ $html = '';
+
+ foreach( $body->childNodes as $child ) {
+ $html .= $child->ownerDocument->saveXML( $child
);
+ }
+
+ return $html;
+ } else {
+ global $wgParser;
+
+ $title = \Title::newFromText( 'Flow', NS_SPECIAL );
+
+ $options = new \ParserOptions;
+ $options->setTidy( true );
+ $options->setEditSection( false );
+
+ $output = $wgParser->parse( $wikitext, $title, $options
);
+ return $output->getText();
+ }
+ }
+
+ public static function convertHtml5ToWikitext( $html ) {
+ global $wgFlowUseParsoid;
+
+ if ( $wgFlowUseParsoid ) {
+ global $wgFlowParsoidURL, $wgFlowParsoidPrefix,
$wgFlowParsoidTimeout;
+
+ return \Http::post(
+ $wgFlowParsoidURL . '/' . $wgFlowParsoidPrefix
. '/Flow',
+ array(
+ 'postData' => array(
+ 'content' => $html,
+ ),
+ 'timeout' => $wgFlowParsoidTimeout
+ )
+ );
+ } else {
+ throw new \MWException( "Editing posts is not supported
without Parsoid" );
+ }
+ }
+}
diff --git a/includes/Templating.php b/includes/Templating.php
index 1bf457f..9be7e69 100644
--- a/includes/Templating.php
+++ b/includes/Templating.php
@@ -3,6 +3,7 @@
namespace Flow;
use Flow\Block\Block;
+use Flow\Block\TopicBlock;
use Flow\Model\PostRevision;
use Flow\Model\Workflow;
use OutputPage;
@@ -71,25 +72,23 @@
return $this->urlGenerator->generateUrl( $workflow, $action,
$query );
}
- public function renderPost( PostRevision $post, Block $block,
PostRevision $root ) {
+ public function renderPost( PostRevision $post, Block $block, $return =
true ) {
return $this->render(
'flow:post.html.php',
array(
'block' => $block,
'post' => $post,
- 'root' => $root,
),
- true
+ $return
);
}
- public function renderTopic( $block, $topic, $root, $user ) {
+ public function renderTopic( PostRevision $root, TopicBlock $block,
$return = true ) {
return $this->render( "flow:topic.html.php", array(
'block' => $block,
- 'topic' => $topic,
+ 'topic' => $block->getWorkflow(),
'root' => $root,
- 'user' => $user,
- ), true );
+ ), $return );
}
}
diff --git a/includes/UrlGenerator.php b/includes/UrlGenerator.php
index 72fdd81..c476797 100644
--- a/includes/UrlGenerator.php
+++ b/includes/UrlGenerator.php
@@ -28,6 +28,6 @@
}
return Title::newFromText( 'Flow/' .
$workflow->getTitleFullText(), NS_SPECIAL )
- ->getFullURL( $query );
+ ->getLinkURL( $query );
}
}
diff --git a/includes/api/ApiQueryFlow.php b/includes/api/ApiQueryFlow.php
index 5059fd9..e8deac3 100644
--- a/includes/api/ApiQueryFlow.php
+++ b/includes/api/ApiQueryFlow.php
@@ -17,7 +17,7 @@
$passedParams = json_decode( $params['params'], true );
$pageTitle = Title::newFromText( $params['page'] );
- $id = $params['workflow'] ? new UUID( $params['workflow'] ) :
null;
+ $id = $params['workflow'] ? UUID::create( $params['workflow'] )
: null;
$this->loader = $this->container['factory.loader.workflow']
->createWorkflowLoader( $pageTitle, $id );
diff --git a/modules/base/ext.flow.base.js b/modules/base/ext.flow.base.js
index d224ff8..0ed82ef 100644
--- a/modules/base/ext.flow.base.js
+++ b/modules/base/ext.flow.base.js
@@ -59,6 +59,38 @@
);
},
+ 'readTopic' : function( pageName, topicId, options ) {
+ var deferredObject = $.Deferred();
+
+ mw.flow.api.read( pageName, topicId, options )
+ .done( function(output) {
+ // Immediate failure modes
+ if (
+ ! output.query ||
+ ! output.query.flow ||
+ output.query.flow._element !==
'block'
+ ) {
+ deferredObject.fail(
'invalid-result', 'Unable to understand the API result' );
+ return;
+ }
+
+ $.each( output.query.flow, function(
index, block ) {
+ // Looping through each block
+ if ( block['block-name'] ===
'topic' ) {
+ // Return this block
+ deferredObject.resolve(
block );
+ }
+ } );
+
+ deferredObject.fail( 'invalid-result',
'Unable to find the topic block in the API result' );
+ } )
+ .fail( function() {
+ deferredObject.fail( arguments );
+ } );
+
+ return deferredObject.promise();
+ },
+
'generateTopicAction' : function( actionName, parameterList,
promiseFilterCallback ) {
return function( workflowId ) {
var deferredObject = $.Deferred();
@@ -77,7 +109,7 @@
'workflow' : workflowId
},
actionName,
- { 'topic_list' :
+ { 'topic' :
requestParams
}, true
).done( function(data) {
@@ -90,12 +122,12 @@
! data.flow ||
! data.flow[actionName] ||
! data.flow[actionName].result
||
- !
data.flow[actionName].result['topic_list']
+ !
data.flow[actionName].result['topic']
) {
deferredObject.reject(
'invalid-result', 'Unable to find appropriate section in result' );
return;
}
- var output =
data.flow[actionName].result['topic_list'];
+ var output =
data.flow[actionName].result['topic'];
deferredObject.resolve( output, data );
} )
@@ -169,5 +201,13 @@
'content'
]
);
+
+mw.flow.api.editPost = mw.flow.api.generateTopicAction(
+ 'edit-post',
+ [
+ 'postId',
+ 'content'
+ ]
+);
});
})( jQuery, mediaWiki );
\ No newline at end of file
diff --git a/modules/discussion/base.css b/modules/discussion/base.css
index af36a95..08de39f 100644
--- a/modules/discussion/base.css
+++ b/modules/discussion/base.css
@@ -913,4 +913,8 @@
.flow-edit-title-textbox {
width: 70%;
+}
+
+.flow-edit-post-form {
+ padding: 4px;
}
\ No newline at end of file
diff --git a/modules/discussion/discussion.js b/modules/discussion/discussion.js
index 8a9f681..42403eb 100644
--- a/modules/discussion/discussion.js
+++ b/modules/discussion/discussion.js
@@ -50,6 +50,20 @@
}
},
+ 'getTopicWorkflowId' : function( $element ) {
+ var $topicContainer = $element.closest( '.flow-topic-container'
);
+ var $container = $element.closest( '.flow-container' );
+
+ if ( $topicContainer.length ) {
+ return $topicContainer.data( 'topic-id' );
+ } else if ( $container.length ) {
+ return $container.data( 'workflow-id' );
+ } else {
+ console.dirxml( $element[0] );
+ throw new Error( "Unable to get a workflow ID" );
+ }
+ },
+
'setupFormHandler' : function(
$container,
submitSelector,
@@ -259,9 +273,7 @@
function() {
$form = $(this).closest( '.flow-reply-form' );
- var workflowId = $(this)
- .closest( '.flow-topic-container' )
- .data( 'topic-id' );
+ var workflowId =
mw.flow.discussion.getTopicWorkflowId( $(this) );
var replyToId = $(this)
.closest( '.flow-post-container' )
@@ -292,6 +304,128 @@
}
);
+ // Overload 'edit post' link.
+ $container.find( '.flow-action-edit-post a' )
+ .click( function(e) {
+ e.preventDefault();
+ var $postContainer = $(this).closest(
'.flow-post' );
+ var $contentContainer = $postContainer.find(
'.flow-post-content' );
+ var workflowId =
mw.flow.discussion.getTopicWorkflowId( $(this) );
+ var pageName = $(this).closest(
'.flow-container' ).data( 'page-title' );
+ var postId = $postContainer.data( 'post-id' );
+
+ if ( $postContainer.find(
'.flow-edit-post-form' ).length ) {
+ return;
+ }
+
+ mw.flow.api.readTopic(
+ pageName,
+ workflowId,
+ {
+ 'no-children' : true,
+ 'postId' : postId
+ }
+ )
+ .done( function( data ) {
+ if ( ! data[0] ||
data[0]['post-id'] != postId ) {
+ console.dir( data );
+ var $errorDiv = $(
'<div/>' )
+ .addClass(
'flow-error' )
+ .text( mw.msg(
'flow-error-other') )
+ .hide()
+ .insertAfter(
$contentContainer )
+ .slideDown();
+ return;
+ }
+
+ var originalContent =
data[0]['content-src']['*'];
+
+ var $postForm = $( '<form />' )
+ .addClass(
'flow-edit-post-form' );
+
+ $postForm
+ .append(
+ $( '<textarea
/>' )
+ .val(
originalContent )
+
.addClass( 'flow-edit-post-content' )
+ )
+ .append(
+ $( '<div/>' )
+
.addClass( 'flow-post-controls' )
+ .append(
+
$( '<a/>' )
+
.text( mw.msg( 'flow-cancel' ) )
+
.addClass( 'flow-cancel-link' )
+
.addClass( 'mw-ui-destructive' )
+
.attr( 'href', '#' )
+
.click( function(e) {
+
e.preventDefault();
+
$postForm.slideUp( 'fast',
+
function() {
+
$contentContainer.show();
+
$postForm.remove();
+
}
+
);
+
} )
+ )
+ .append(
+
$( '<input />' )
+
.attr( 'type', 'submit' )
+
.addClass( 'mw-ui-button' )
+
.addClass( 'mw-ui-primary' )
+
.addClass( 'flow-edit-post-submit' )
+
.val( mw.msg( 'flow-edit-post-submit' ) )
+ )
+ )
+ .insertAfter(
$contentContainer );
+
+ $contentContainer.hide();
+
+
mw.flow.discussion.setupFormHandler(
+ $postContainer,
+
'.flow-edit-post-submit',
+ mw.flow.api.editPost,
+ function() {
+ var content =
$postForm.find( '.flow-edit-post-content' ).val();
+
+ return [
workflowId, postId, content ];
+ },
+ function( workflowId,
postId, content ) {
+ return content;
+ },
+ function( promise ) {
+ promise.done(
function(output) {
+
$contentContainer
+
.empty()
+
.append(
+
$(output.rendered)
+
.find('.flow-post-content')
+
.children()
+
);
+ } );
+ }
+ );
+
+
mw.flow.discussion.setupEmptyDisabler(
+
'form.flow-edit-post-form',
+ [
+
'.flow-edit-post-content'
+ ],
+ '.flow-edit-post-submit'
+ );
+ } )
+ .fail( function() {
+ var $errorDiv = $( '<div/>' )
+ .addClass( 'flow-error'
)
+ .hide();
+
+ mw.flow.discussion.handleError(
$errorDiv, arguments );
+
+ $errorDiv.insertAfter(
$contentContainer )
+ .slideDown();
+ } );
+ } );
+
// Overload 'edit title' link.
$container.find( '.flow-action-edit-title a' )
.click( function(e) {
diff --git a/templates/edit-post.html.php b/templates/edit-post.html.php
new file mode 100644
index 0000000..e05b699
--- /dev/null
+++ b/templates/edit-post.html.php
@@ -0,0 +1,35 @@
+<?php
+
+echo Html::openElement( 'form', array(
+ 'method' => 'POST',
+ 'action' => $this->generateUrl( $topic->getId(), 'edit-post' ),
+) );
+$editToken = $user->getEditToken( 'flow' );
+if ( $block->hasErrors() ) {
+ echo '<ul>';
+ foreach ( $block->getErrors() as $error ) {
+ echo '<li>', $error->escaped() . '</li>'; // the pain ...
+ }
+ echo '</ul>';
+}
+
+$postWikitext = \Flow\ParsoidUtils::convertHtml5ToWikitext(
$post->getContent() );
+
+echo Html::element( 'input', array(
+ 'type' => 'hidden',
+ 'name' => 'wpEditToken',
+ 'value' => $user->getEditToken( 'flow' ),
+ ) ),
+ Html::element( 'input', array(
+ 'type' => 'hidden',
+ 'name' => $block->getName() . '[postId]',
+ 'value' => $post->getPostId()->getHex(),
+ ) ),
+ Html::textarea( $block->getName() . '[content]', $postWikitext ),
+ Html::element( 'input', array(
+ 'type' => 'submit',
+ 'class' => 'mw-ui-button mw-ui-primary',
+ 'value' => wfMessage( 'flow-edit-post-submit' )->plain()
+ ) ),
+ '</form>';
+
diff --git a/templates/post.html.php b/templates/post.html.php
index c5803fa..c4e925f 100644
--- a/templates/post.html.php
+++ b/templates/post.html.php
@@ -3,12 +3,12 @@
$editToken = $user->getEditToken( 'flow' );
$self = $this;
-$postAction = function( $action, array $data = array(), $class = '' ) use(
$self, $block, $root, $editToken ) {
+$postAction = function( $action, array $data = array(), $class = '' ) use(
$self, $block, $editToken ) {
// actions that change things must be post requests
$output = '';
$output .= Html::openElement( 'form', array(
'method' => 'POST',
- 'action' => $self->generateUrl( $root->getPostId(), $action )
+ 'action' => $self->generateUrl( $block->getWorkflowId(),
$action )
) );
$output .= Html::element( 'input', array( 'type' => 'hidden', 'name' =>
'wpEditToken', 'value' => $editToken) );
foreach ( $data as $name => $value ) {
@@ -27,8 +27,25 @@
return $output;
};
-$renderPost = function( $post ) use( $self, $block, $root ) {
- echo $self->renderPost( $post, $block, $root );
+$getAction = function( $action, $data = array(), $class = '' ) use ( $post,
$self, $block ) {
+ $url = $self->generateUrl(
+ $block->getWorkflowId(),
+ $action,
+ array(
+ $block->getName() . '[postId]' =>
$post->getPostId()->getHex(),
+ )
+ );
+ return Html::element( 'a',
+ array(
+ 'href' => $url,
+ 'class' => $class,
+ ),
+ wfMessage( "flow-post-action-$action" )->plain()
+ );
+};
+
+$renderPost = function( $post ) use( $self, $block ) {
+ echo $self->renderPost( $post, $block );
};
echo Html::openElement( 'div', array(
@@ -57,7 +74,7 @@
$actions['restore'] = $postAction( 'restore-post', array( 'postId' =>
$post->getPostId()->getHex() ), 'mw-ui-constructive' );
$actions['history'] = Html::element( 'a', array(
- 'href' => $self->generateUrl( $root->getPostId(),
'post-history', array(
+ 'href' => $self->generateUrl( $block->getWorkflowId(),
'post-history', array(
$block->getName() . '[postId]' =>
$post->getPostId()->getHex(),
) ),
), wfMessage( 'flow-post-action-history' )->plain() );
@@ -65,15 +82,13 @@
$user = Html::element( 'span', null, $post->getUserText() );
$content = $post->getContent();
$actions['delete'] = $postAction( 'delete-post', array( 'postId' =>
$post->getPostId()->getHex() ), 'mw-ui-destructive' );
- $actions['history'] = Html::element( 'a', array(
- 'href' => $self->generateUrl( $root->getPostId(),
'post-history', array(
- $block->getName() . '[postId]' =>
$post->getPostId()->getHex(),
- ) ),
- ), wfMessage( 'flow-post-action-history' )->plain() );
+ $actions['history'] = $getAction( 'post-history' );
+ $actions['permalink'] = $getAction( 'view' );
+ $actions['edit-post'] = $getAction( 'edit-post' );
$replyForm = Html::openElement( 'form', array(
'method' => 'POST',
// root post id is same as topic workflow id
- 'action' => $self->generateUrl( $root->getPostId(),
'reply' ),
+ 'action' => $self->generateUrl(
$block->getWorkflowId(), 'reply' ),
'class' => 'flow-reply-form',
) );
$replyForm .= Html::element( 'input', array( 'type' => 'hidden', 'name'
=> 'wpEditToken', 'value' => $editToken) );
diff --git a/templates/topic.html.php b/templates/topic.html.php
index 6b36bd8..2d24847 100644
--- a/templates/topic.html.php
+++ b/templates/topic.html.php
@@ -1,16 +1,4 @@
<?php
-// yes, this is a horrible quick hack
-// probably be better off if the templates were classes that were called as
-// $template->render( $options );
-// or some such
-
-$self = $this;
-
-$editToken = $user->getEditToken( 'flow' );
-
-$renderPost = function( $post ) use( $self, $block, $root, $user ) {
- echo $self->renderPost( $post, $block, $root );
-};
$title = $root->getContent();
@@ -26,7 +14,7 @@
<div class="flow-titlebar">
<div class="flow-topic-title">
<div class="flow-realtitle">
-<?php echo htmlspecialchars( $title ); ?>
+ <?php echo htmlspecialchars( $title ); ?>
</div>
</div>
<div class="flow-topiccontrols">
@@ -38,11 +26,26 @@
<div class="flow-actionbox-pokey"> </div>
<div class="flow-topic-actionbox">
<ul>
-<?php
-echo Html::rawElement( 'li', array( 'class' => 'flow-action-edit-title' ),
Html::rawElement( 'a', array(
- 'href' => $this->generateUrl( $root->getPostId(), 'edit-title' )
- ), wfMessage( 'flow-topic-action-edit-title' ) ) );
-?>
+ <li class="flow-action-edit-title">
+ <?php
+ echo Html::rawElement( 'a',
+ array(
+ 'href' =>
$this->generateUrl( $root->getPostId(), 'edit-title' )
+ ),
+ wfMessage(
'flow-topic-action-edit-title' )
+ );
+ ?>
+ </li>
+ <li class="flow-action-topic-history">
+ <?php
+ echo Html::rawElement( 'a',
+ array(
+ 'href' =>
$this->generateUrl( $root->getPostId(), 'topic-history' )
+ ),
+ wfMessage(
'flow-topic-action-history' )
+ );
+ ?>
+ </li>
</ul>
</div>
</div>
@@ -54,7 +57,7 @@
<?php
foreach( $root->getChildren() as $child ) {
- $renderPost( $child );
+ echo $this->renderPost( $child, $block, $root );
}
?>
</div>
--
To view, visit https://gerrit.wikimedia.org/r/78933
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Ie62ff67ae09ec131ae49acce3ffe779311203842
Gerrit-PatchSet: 7
Gerrit-Project: mediawiki/extensions/Flow
Gerrit-Branch: master
Gerrit-Owner: EBernhardson (WMF) <[email protected]>
Gerrit-Reviewer: EBernhardson (WMF) <[email protected]>
Gerrit-Reviewer: Matthias Mullie <[email protected]>
Gerrit-Reviewer: Werdna <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits