jenkins-bot has submitted this change and it was merged.
Change subject: Undo
......................................................................
Undo
Implements undo actions for edit-post, edit-header and
edit-topic-summary.
Bug: T89198
Change-Id: I6b45a2c5cdaf40f15a8b02ae5ba707529218538e
---
M FlowActions.php
M Resources.php
M autoload.php
M container.php
M handlebars/compiled/flow_block_board-history.handlebars.php
A handlebars/compiled/flow_block_header_undo_edit.handlebars.php
M handlebars/compiled/flow_block_topic.handlebars.php
M handlebars/compiled/flow_block_topic_history.handlebars.php
M handlebars/compiled/flow_block_topic_moderate_post.handlebars.php
M handlebars/compiled/flow_block_topic_moderate_topic.handlebars.php
A handlebars/compiled/flow_block_topic_undo_edit.handlebars.php
M handlebars/compiled/flow_block_topiclist.handlebars.php
A handlebars/compiled/flow_block_topicsummary_undo_edit.handlebars.php
M handlebars/compiled/flow_post.handlebars.php
A handlebars/flow_block_header_undo_edit.handlebars
A handlebars/flow_block_topic_undo_edit.handlebars
A handlebars/flow_block_topicsummary_undo_edit.handlebars
M handlebars/flow_edit_post.partial.handlebars
M handlebars/flow_history_line.partial.handlebars
M handlebars/flow_moderation_actions_list.partial.handlebars
M i18n/en.json
M i18n/qqq.json
A includes/Actions/UndoEditHeaderAction.php
A includes/Actions/UndoEditPostAction.php
A includes/Actions/UndoEditTopicSummaryAction.php
M includes/Block/Header.php
M includes/Block/Topic.php
M includes/Block/TopicSummary.php
M includes/Formatter/RevisionFormatter.php
A includes/Formatter/RevisionUndoViewFormatter.php
M includes/Formatter/RevisionViewFormatter.php
M includes/Formatter/RevisionViewQuery.php
M includes/TemplateHelper.php
M includes/UrlGenerator.php
M includes/View.php
A includes/api/ApiFlowUndoEditHeader.php
A includes/api/ApiFlowUndoEditPost.php
A includes/api/ApiFlowUndoEditTopicSummary.php
M modules/engine/components/board/features/flow-board-preview.js
39 files changed, 1,107 insertions(+), 32 deletions(-)
Approvals:
Matthias Mullie: Looks good to me, approved
jenkins-bot: Verified
diff --git a/FlowActions.php b/FlowActions.php
index 4411694..93e6d5e 100644
--- a/FlowActions.php
+++ b/FlowActions.php
@@ -67,7 +67,7 @@
Header::MODERATED_NONE => '',
),
'links' => array( 'board-history', 'diff-header', 'workflow',
'header-revision' ),
- 'actions' => array( 'edit-header' ),
+ 'actions' => array( 'edit-header', 'undo-edit-header' ),
'history' => array(
'i18n-message' => 'flow-rev-message-edit-header',
'i18n-params' => array(
@@ -78,6 +78,38 @@
),
'handler-class' => 'Flow\Actions\EditHeaderAction',
'editcount' => true,
+ ),
+
+ // @todo this is almost copy/paste from edit-header except the
handler-class. find
+ // a way to share.
+ 'undo-edit-header' => array(
+ 'performs-writes' => true,
+ 'log_type' => false,
+ 'rc_insert' => true,
+ 'permissions' => array(
+ Header::MODERATED_NONE => '',
+ ),
+ 'links' => array( 'board-history', 'diff-header', 'workflow',
'header-revision' ),
+ 'actions' => array( 'edit-header', 'undo-edit-header' ),
+ 'history' => array(
+ 'i18n-message' => 'flow-rev-message-edit-header',
+ 'i18n-params' => array(
+ 'user-links',
+ 'user-text',
+ ),
+ 'class' => 'flow-history-edit-header',
+ ),
+ 'handler-class' => 'Flow\Actions\UndoEditHeaderAction',
+ 'editcount' => true,
+ // theis modules/moduleStyles is repeated in all the undo-*
actions. Find a way to share.
+ 'modules' => array( 'ext.flow.undo' ),
+ 'moduleStyles' => array(
+ 'mediawiki.ui.button',
+ 'mediawiki.ui.input',
+ 'ext.flow.styles.base',
+ 'ext.flow.board.styles',
+ 'ext.flow.board.topic.styles',
+ ),
),
'create-topic-summary' => array(
@@ -117,7 +149,7 @@
PostSummary::MODERATED_SUPPRESSED => array(
'flow-suppress' ),
),
'links' => array( 'topic', 'topic-history',
'diff-post-summary', 'watch-topic', 'unwatch-topic', 'summary-revision' ),
- 'actions' => array( 'edit-topic-summary', 'lock-topic',
'restore-topic' ),
+ 'actions' => array( 'edit-topic-summary', 'lock-topic',
'restore-topic', 'undo-edit-topic-summary' ),
'history' => array(
'i18n-message' => 'flow-rev-message-edit-topic-summary',
'i18n-params' => array(
@@ -129,6 +161,42 @@
),
'handler-class' => 'Flow\Actions\EditTopicSummaryAction',
'editcount' => true,
+ ),
+
+ // @todo this is almost copy/paste from edit-topic-summary except the
handler class. find a
+ // way to share
+ 'undo-edit-topic-summary' => array(
+ 'performs-writes' => true,
+ 'log_type' => false,
+ 'rc_insert' => true,
+ 'permissions' => array(
+ PostSummary::MODERATED_NONE => '',
+ PostSummary::MODERATED_LOCKED => array( 'flow-lock',
'flow-delete', 'flow-suppress' ),
+ PostSummary::MODERATED_HIDDEN => array( 'flow-hide',
'flow-delete', 'flow-suppress' ),
+ PostSummary::MODERATED_DELETED => array( 'flow-delete',
'flow-suppress' ),
+ PostSummary::MODERATED_SUPPRESSED => array(
'flow-suppress' ),
+ ),
+ 'links' => array( 'topic', 'topic-history',
'diff-post-summary', 'watch-topic', 'unwatch-topic' ),
+ 'actions' => array( 'edit-topic-summary', 'lock-topic',
'restore-topic', 'undo-edit-topic-summary' ),
+ 'history' => array(
+ 'i18n-message' => 'flow-rev-message-edit-topic-summary',
+ 'i18n-params' => array(
+ 'user-links',
+ 'user-text',
+ 'post-of-summary',
+ ),
+ 'class' => 'flow-history-edit-topic-summary',
+ ),
+ 'handler-class' => 'Flow\Actions\UndoEditTopicSummaryAction',
+ 'editcount' => true,
+ 'modules' => array( 'ext.flow.undo' ),
+ 'moduleStyles' => array(
+ 'mediawiki.ui.button',
+ 'mediawiki.ui.input',
+ 'ext.flow.styles.base',
+ 'ext.flow.board.styles',
+ 'ext.flow.board.topic.styles',
+ ),
),
'edit-title' => array(
@@ -200,7 +268,7 @@
PostRevision::MODERATED_NONE => '',
),
'links' => array( 'post-history', 'topic-history', 'topic',
'post', 'diff-post', 'post-revision' ),
- 'actions' => array( 'reply', 'thank', 'edit-post',
'restore-post', 'hide-post', 'delete-post', 'suppress-post' ),
+ 'actions' => array( 'reply', 'thank', 'edit-post',
'restore-post', 'hide-post', 'delete-post', 'suppress-post', 'undo-edit-post' ),
'history' => array(
'i18n-message' => 'flow-rev-message-edit-post',
'i18n-params' => array(
@@ -218,6 +286,44 @@
'editcount' => true,
),
+ // @todo this is almost (but not quite) copy/paste from 'edit-post'.
find a way to share?
+ 'undo-edit-post' => array(
+ 'performs-writes' => true,
+ 'log_type' => false, // maybe?
+ 'rc_insert' => true,
+ 'permissions' => array(
+ PostRevision::MODERATED_NONE => '',
+ ),
+ 'root-permissions' => array(
+ PostRevision::MODERATED_NONE => '',
+ ),
+ 'links' => array( 'post-history', 'topic-history', 'topic',
'post', 'diff-post', 'post-revision' ),
+ 'actions' => array( 'reply', 'thank', 'edit-post',
'restore-post', 'hide-post', 'delete-post', 'suppress-post', 'undo-edit-post' ),
+ 'history' => array(
+ 'i18n-message' => 'flow-rev-message-edit-post',
+ 'i18n-params' => array(
+ 'user-links',
+ 'user-text',
+ 'post-url',
+ 'topic-of-post',
+ ),
+ 'class' => 'flow-history-edit-post',
+ ),
+ 'handler-class' => 'Flow\Actions\UndoEditPostAction',
+ 'watch' => array(
+ 'immediate' => array(
'Flow\\Data\\Listener\\ImmediateWatchTopicListener', 'getCurrentUser' ),
+ ),
+ 'editcount' => true,
+ 'modules' => array( 'ext.flow.undo' ),
+ 'moduleStyles' => array(
+ 'mediawiki.ui.button',
+ 'mediawiki.ui.input',
+ 'ext.flow.styles.base',
+ 'ext.flow.board.styles',
+ 'ext.flow.board.topic.styles',
+ ),
+ ),
+
'hide-post' => array(
'performs-writes' => true,
'log_type' => false,
diff --git a/Resources.php b/Resources.php
index 6985137..9796253 100644
--- a/Resources.php
+++ b/Resources.php
@@ -268,7 +268,7 @@
'wikiglyph/flow-override.less',
),
) + $mobile,
- 'ext.flow.styles' => $flowResourceTemplate + array(
+ 'ext.flow.styles.base' => $flowResourceTemplate + array(
'styles' => array(
'styles/common.less',
'styles/errors.less',
@@ -399,7 +399,20 @@
'engine/misc/flow-baseconvert.js',
),
'dependencies' => array(
- 'ext.flow.components'
+ 'ext.flow.components',
+ ),
+ ) + $mobile,
+ 'ext.flow.undo' => $flowResourceTemplate + array(
+ 'scripts' => array(
+ // this must be last (of everything loaded. otherwise
a components
+ // can be initialized before all the mixins are loaded.
Can we mixin
+ // after initialization?)
+ 'flow-initialize.js',
+ ),
+ // minimal subset for the undo pages
+ 'dependencies' => array(
+ 'ext.flow.components',
+ 'ext.flow.preview',
),
) + $mobile,
'ext.flow.editor' => $flowResourceTemplate + array(
diff --git a/autoload.php b/autoload.php
index a7c4532..0ccf082 100644
--- a/autoload.php
+++ b/autoload.php
@@ -17,6 +17,9 @@
'ApiFlowModerateTopic' => __DIR__ .
'/includes/api/ApiFlowModerateTopic.php',
'ApiFlowNewTopic' => __DIR__ . '/includes/api/ApiFlowNewTopic.php',
'ApiFlowReply' => __DIR__ . '/includes/api/ApiFlowReply.php',
+ 'ApiFlowUndoEditHeader' => __DIR__ .
'/includes/api/ApiFlowUndoEditHeader.php',
+ 'ApiFlowUndoEditPost' => __DIR__ .
'/includes/api/ApiFlowUndoEditPost.php',
+ 'ApiFlowUndoEditTopicSummary' => __DIR__ .
'/includes/api/ApiFlowUndoEditTopicSummary.php',
'ApiFlowViewHeader' => __DIR__ . '/includes/api/ApiFlowViewHeader.php',
'ApiFlowViewPost' => __DIR__ . '/includes/api/ApiFlowViewPost.php',
'ApiFlowViewTopic' => __DIR__ . '/includes/api/ApiFlowViewTopic.php',
@@ -45,6 +48,9 @@
'Flow\\Actions\\ReplyAction' => __DIR__ .
'/includes/Actions/ReplyAction.php',
'Flow\\Actions\\RestorePostAction' => __DIR__ .
'/includes/Actions/RestorePostAction.php',
'Flow\\Actions\\RestoreTopicAction' => __DIR__ .
'/includes/Actions/RestoreTopicAction.php',
+ 'Flow\\Actions\\UndoEditHeaderAction' => __DIR__ .
'/includes/Actions/UndoEditHeaderAction.php',
+ 'Flow\\Actions\\UndoEditPostAction' => __DIR__ .
'/includes/Actions/UndoEditPostAction.php',
+ 'Flow\\Actions\\UndoEditTopicSummaryAction' => __DIR__ .
'/includes/Actions/UndoEditTopicSummaryAction.php',
'Flow\\Actions\\ViewAction' => __DIR__ .
'/includes/Actions/ViewAction.php',
'Flow\\Actions\\ViewHeaderAction' => __DIR__ .
'/includes/Actions/ViewHeaderAction.php',
'Flow\\Actions\\ViewTopicSummaryAction' => __DIR__ .
'/includes/Actions/ViewTopicSummaryAction.php',
@@ -162,6 +168,7 @@
'Flow\\Formatter\\RecentChangesRow' => __DIR__ .
'/includes/Formatter/RecentChangesQuery.php',
'Flow\\Formatter\\RevisionDiffViewFormatter' => __DIR__ .
'/includes/Formatter/RevisionDiffViewFormatter.php',
'Flow\\Formatter\\RevisionFormatter' => __DIR__ .
'/includes/Formatter/RevisionFormatter.php',
+ 'Flow\\Formatter\\RevisionUndoViewFormatter' => __DIR__ .
'/includes/Formatter/RevisionUndoViewFormatter.php',
'Flow\\Formatter\\RevisionViewFormatter' => __DIR__ .
'/includes/Formatter/RevisionViewFormatter.php',
'Flow\\Formatter\\RevisionViewQuery' => __DIR__ .
'/includes/Formatter/RevisionViewQuery.php',
'Flow\\Formatter\\SinglePostQuery' => __DIR__ .
'/includes/Formatter/SinglePostQuery.php',
diff --git a/container.php b/container.php
index f2231d9..479cd8b 100644
--- a/container.php
+++ b/container.php
@@ -905,19 +905,22 @@
$c['query.header.view'] = function( $c ) {
return new Flow\Formatter\HeaderViewQuery(
$c['storage'],
- $c['repository.tree']
+ $c['repository.tree'],
+ $c['permissions']
);
};
$c['query.post.view'] = function( $c ) {
return new Flow\Formatter\PostViewQuery(
$c['storage'],
- $c['repository.tree']
+ $c['repository.tree'],
+ $c['permissions']
);
};
$c['query.postsummary.view'] = function( $c ) {
return new Flow\Formatter\PostSummaryViewQuery(
$c['storage'],
- $c['repository.tree']
+ $c['repository.tree'],
+ $c['permissions']
);
};
$c['formatter.recentchanges'] = function( $c ) {
@@ -1189,4 +1192,10 @@
return new \Flow\Data\Listener\EditCountListener( $c['flow_actions'] );
};
+$c['formatter.undoedit'] = function( $c ) {
+ return new Flow\Formatter\RevisionUndoViewFormatter(
+ $c['formatter.revisionview']
+ );
+};
+
return $c;
diff --git a/handlebars/compiled/flow_block_board-history.handlebars.php
b/handlebars/compiled/flow_block_board-history.handlebars.php
index 00fa03e..61987c7 100644
--- a/handlebars/compiled/flow_block_board-history.handlebars.php
+++ b/handlebars/compiled/flow_block_board-history.handlebars.php
@@ -41,7 +41,9 @@
href="'.htmlentities((string)((isset($in['links']['post']['url']) &&
is_array($in['links']['post'])) ? $in['links']['post']['url'] : null),
ENT_QUOTES, 'UTF-8').'"
title="'.htmlentities((string)((isset($in['links']['post']['title']) &&
is_array($in['links']['post'])) ? $in['links']['post']['title'] : null),
ENT_QUOTES, 'UTF-8').'">'.((LCRun3::ifvar($cx, ((isset($in['moderationIcons'])
&& is_array($in)) ? $in['moderationIcons'] : null))) ? '<span class="wikiglyph
wikiglyph-link"></span> ' : '').''.LCRun3::ch($cx, 'l10n',
array(array(LCRun3::ch($cx, 'concat',
array(array('flow-',((isset($in['moderationType']) && is_array($in)) ?
$in['moderationType'] : null),'-action-view'),array()), 'raw')),array()),
'encq').'</a>'.htmlentities((string)((isset($in['noop']) && is_array($in)) ?
$in['noop'] : null), ENT_QUOTES, 'UTF-8').'</li>' : '').'';}).'</section>
-<section>'.((LCRun3::ifvar($cx, ((isset($in['actions']['hide']) &&
is_array($in['actions'])) ? $in['actions']['hide'] : null))) ?
'<li>'.htmlentities((string)((isset($in['noop']) && is_array($in)) ?
$in['noop'] : null), ENT_QUOTES, 'UTF-8').'<a
class="'.htmlentities((string)((isset($in['moderationMwUiClass']) &&
is_array($in)) ? $in['moderationMwUiClass'] : null), ENT_QUOTES, 'UTF-8').'
mw-ui-quiet"
+<section>'.LCRun3::hbch($cx, 'ifCond',
array(array(((isset($in['moderationType']) && is_array($in)) ?
$in['moderationType'] : null),'===','history'),array()), $in, false,
function($cx, $in) {return ''.((LCRun3::ifvar($cx,
((isset($in['actions']['undo']) && is_array($in['actions'])) ?
$in['actions']['undo'] : null))) ?
'<li>'.htmlentities((string)((isset($in['noop']) && is_array($in)) ?
$in['noop'] : null), ENT_QUOTES, 'UTF-8').'<a
class="'.htmlentities((string)((isset($in['moderationMwUiClass']) &&
is_array($in)) ? $in['moderationMwUiClass'] : null), ENT_QUOTES, 'UTF-8').'
mw-ui-quiet"
+
href="'.htmlentities((string)((isset($in['actions']['undo']['url']) &&
is_array($in['actions']['undo'])) ? $in['actions']['undo']['url'] : null),
ENT_QUOTES, 'UTF-8').'"
+
>'.htmlentities((string)((isset($in['actions']['undo']['title']) &&
is_array($in['actions']['undo'])) ? $in['actions']['undo']['title'] : null),
ENT_QUOTES, 'UTF-8').'</a>'.htmlentities((string)((isset($in['noop']) &&
is_array($in)) ? $in['noop'] : null), ENT_QUOTES, 'UTF-8').'</li>' :
'').'';}).''.((LCRun3::ifvar($cx, ((isset($in['actions']['hide']) &&
is_array($in['actions'])) ? $in['actions']['hide'] : null))) ?
'<li>'.htmlentities((string)((isset($in['noop']) && is_array($in)) ?
$in['noop'] : null), ENT_QUOTES, 'UTF-8').'<a
class="'.htmlentities((string)((isset($in['moderationMwUiClass']) &&
is_array($in)) ? $in['moderationMwUiClass'] : null), ENT_QUOTES, 'UTF-8').'
mw-ui-quiet"
href="'.htmlentities((string)((isset($in['actions']['hide']['url']) &&
is_array($in['actions']['hide'])) ? $in['actions']['hide']['url'] : null),
ENT_QUOTES, 'UTF-8').'"
title="'.htmlentities((string)((isset($in['actions']['hide']['title']) &&
is_array($in['actions']['hide'])) ? $in['actions']['hide']['title'] : null),
ENT_QUOTES, 'UTF-8').'"
data-flow-interactive-handler="moderationDialog"
@@ -118,7 +120,6 @@
'.((LCRun3::ifvar($cx, ((isset($in['size']) && is_array($in)) ? $in['size'] :
null))) ? ' <span class="mw-changeslist-separator">. .</span>
'.LCRun3::ch($cx, 'showCharacterDifference',
array(array(((isset($in['size']['old']) && is_array($in['size'])) ?
$in['size']['old'] : null),((isset($in['size']['new']) &&
is_array($in['size'])) ? $in['size']['new'] : null)),array()), 'encq').'
' : '').'
-
<ul class="flow-history-moderation-menu">
'.LCRun3::p($cx, 'flow_moderation_actions_list',
array(array($in),array('moderationType'=>'history','moderationTarget'=>'post','moderationTemplate'=>'post','moderationMwUiClass'=>'mw-ui-anchor','moderationIcons'=>false))).'</ul>
';},),
diff --git a/handlebars/compiled/flow_block_header_undo_edit.handlebars.php
b/handlebars/compiled/flow_block_header_undo_edit.handlebars.php
new file mode 100644
index 0000000..add3c7e
--- /dev/null
+++ b/handlebars/compiled/flow_block_header_undo_edit.handlebars.php
@@ -0,0 +1,77 @@
+<?php return function ($in, $debugopt = 1) {
+ $cx = array(
+ 'flags' => array(
+ 'jstrue' => false,
+ 'jsobj' => false,
+ 'spvar' => true,
+ 'prop' => false,
+ 'method' => false,
+ 'mustlok' => false,
+ 'mustsec' => false,
+ 'echo' => false,
+ 'debug' => $debugopt,
+ ),
+ 'constants' => array(),
+ 'helpers' => array( 'l10n' => 'Flow\TemplateHelper::l10n',
+ 'html' => 'Flow\TemplateHelper::htmlHelper',
+ 'l10nParse' => 'Flow\TemplateHelper::l10nParse',
+ 'diffUndo' => 'Flow\TemplateHelper::diffUndo',
+),
+ 'blockhelpers' => array(),
+ 'hbhelpers' => array(),
+ 'partials' => array('flow_errors' => function ($cx, $in) {return '<div
class="flow-error-container">
+'.((LCRun3::ifvar($cx, ((isset($cx['sp_vars']['root']['errors']) &&
is_array($cx['sp_vars']['root'])) ? $cx['sp_vars']['root']['errors'] : null)))
? ' <div class="flow-errors errorbox">
+ <ul>
+'.LCRun3::sec($cx, ((isset($cx['sp_vars']['root']['errors']) &&
is_array($cx['sp_vars']['root'])) ? $cx['sp_vars']['root']['errors'] : null),
$in, true, function($cx, $in) {return '
<li>'.LCRun3::ch($cx, 'html', array(array(((isset($in['message']) &&
is_array($in)) ? $in['message'] : null)),array()), 'encq').'</li>
+';}).' </ul>
+ </div>
+' : '').'</div>
+';},'flow_form_buttons' => function ($cx, $in) {return '<button
data-flow-api-handler="preview"
+ data-flow-api-target="< form textarea"
+ name="preview"
+ data-role="action"
+ class="mw-ui-button mw-ui-progressive mw-ui-quiet mw-ui-flush-right
flow-form-action-preview flow-js"
+
+>'.LCRun3::ch($cx, 'l10n', array(array('flow-preview'),array()),
'encq').'</button>
+
+<button data-flow-interactive-handler="cancelForm"
+ data-role="cancel"
+ type="reset"
+ class="mw-ui-button mw-ui-destructive mw-ui-quiet mw-ui-flush-right
flow-js"
+
+>'.LCRun3::ch($cx, 'l10n', array(array('flow-cancel'),array()),
'encq').'</button>
+';},),
+ 'scopes' => array($in),
+ 'sp_vars' => array('root' => $in),
+
+ );
+
+ return '<div class="flow-board">
+'.((LCRun3::ifvar($cx, ((isset($in['undo']['possible']) &&
is_array($in['undo'])) ? $in['undo']['possible'] : null))) ? '
<p>'.LCRun3::ch($cx, 'l10n', array(array('flow-undo-edit-content'),array()),
'encq').'</p>
+' : ' <p class="error">'.LCRun3::ch($cx, 'l10n',
array(array('flow-undo-edit-failure'),array()), 'encq').'</p>
+').'
+'.LCRun3::p($cx, 'flow_errors', array(array($in),array())).'
+'.((LCRun3::ifvar($cx, ((isset($in['undo']['possible']) &&
is_array($in['undo'])) ? $in['undo']['possible'] : null))) ? '
'.LCRun3::ch($cx, 'diffUndo', array(array(((isset($in['undo']['diff_content'])
&& is_array($in['undo'])) ? $in['undo']['diff_content'] : null)),array()),
'encq').'
+' : '').'
+ <form method="POST"
action="'.htmlentities((string)((isset($in['links']['undo-edit-header']['url'])
&& is_array($in['links']['undo-edit-header'])) ?
$in['links']['undo-edit-header']['url'] : null), ENT_QUOTES, 'UTF-8').'"
class="flow-post">
+ <input type="hidden" name="wpEditToken"
value="'.htmlentities((string)((isset($cx['sp_vars']['root']['rootBlock']['editToken'])
&& is_array($cx['sp_vars']['root']['rootBlock'])) ?
$cx['sp_vars']['root']['rootBlock']['editToken'] : null), ENT_QUOTES,
'UTF-8').'" />
+ <input type="hidden" name="header_prev_revision"
value="'.htmlentities((string)((isset($in['current']['revisionId']) &&
is_array($in['current'])) ? $in['current']['revisionId'] : null), ENT_QUOTES,
'UTF-8').'" />
+
+ <textarea name="topic_content"
+ class="mw-ui-input"
+ data-role="content"
+
data-flow-preview-template="flow_header_detail.partial"
+
data-flow-preview-title="'.htmlentities((string)((isset($in['articleTitle']) &&
is_array($in)) ? $in['articleTitle'] : null), ENT_QUOTES, 'UTF-8').'"
+ >'.((LCRun3::ifvar($cx, ((isset($in['submitted']['content']) &&
is_array($in['submitted'])) ? $in['submitted']['content'] : null))) ?
''.htmlentities((string)((isset($in['submitted']['content']) &&
is_array($in['submitted'])) ? $in['submitted']['content'] : null), ENT_QUOTES,
'UTF-8').'' : ''.((LCRun3::ifvar($cx, ((isset($in['undo']['possible']) &&
is_array($in['undo'])) ? $in['undo']['possible'] : null))) ?
''.htmlentities((string)((isset($in['undo']['content']) &&
is_array($in['undo'])) ? $in['undo']['content'] : null), ENT_QUOTES,
'UTF-8').'' :
''.htmlentities((string)((isset($in['current']['content']['content']) &&
is_array($in['current']['content'])) ? $in['current']['content']['content'] :
null), ENT_QUOTES, 'UTF-8').'').'').'</textarea>
+
+ <div class="flow-form-actions flow-form-collapsible">
+ <button class="mw-ui-button
mw-ui-constructive">'.LCRun3::ch($cx, 'l10n',
array(array('flow-edit-header-submit'),array()), 'encq').'</button>
+'.LCRun3::p($cx, 'flow_form_buttons', array(array($in),array())).'
<small class="flow-terms-of-use plainlinks">'.LCRun3::ch($cx,
'l10nParse', array(array('flow-terms-of-use-edit'),array()), 'encq').'
+ </small>
+ </div>
+ </form>
+</div>
+
+';
+}
+?>
\ No newline at end of file
diff --git a/handlebars/compiled/flow_block_topic.handlebars.php
b/handlebars/compiled/flow_block_topic.handlebars.php
index 7aa1050..b8542fd 100644
--- a/handlebars/compiled/flow_block_topic.handlebars.php
+++ b/handlebars/compiled/flow_block_topic.handlebars.php
@@ -91,7 +91,9 @@
href="'.htmlentities((string)((isset($in['links']['post']['url']) &&
is_array($in['links']['post'])) ? $in['links']['post']['url'] : null),
ENT_QUOTES, 'UTF-8').'"
title="'.htmlentities((string)((isset($in['links']['post']['title']) &&
is_array($in['links']['post'])) ? $in['links']['post']['title'] : null),
ENT_QUOTES, 'UTF-8').'">'.((LCRun3::ifvar($cx, ((isset($in['moderationIcons'])
&& is_array($in)) ? $in['moderationIcons'] : null))) ? '<span class="wikiglyph
wikiglyph-link"></span> ' : '').''.LCRun3::ch($cx, 'l10n',
array(array(LCRun3::ch($cx, 'concat',
array(array('flow-',((isset($in['moderationType']) && is_array($in)) ?
$in['moderationType'] : null),'-action-view'),array()), 'raw')),array()),
'encq').'</a>'.htmlentities((string)((isset($in['noop']) && is_array($in)) ?
$in['noop'] : null), ENT_QUOTES, 'UTF-8').'</li>' : '').'';}).'</section>
-<section>'.((LCRun3::ifvar($cx, ((isset($in['actions']['hide']) &&
is_array($in['actions'])) ? $in['actions']['hide'] : null))) ?
'<li>'.htmlentities((string)((isset($in['noop']) && is_array($in)) ?
$in['noop'] : null), ENT_QUOTES, 'UTF-8').'<a
class="'.htmlentities((string)((isset($in['moderationMwUiClass']) &&
is_array($in)) ? $in['moderationMwUiClass'] : null), ENT_QUOTES, 'UTF-8').'
mw-ui-quiet"
+<section>'.LCRun3::hbch($cx, 'ifCond',
array(array(((isset($in['moderationType']) && is_array($in)) ?
$in['moderationType'] : null),'===','history'),array()), $in, false,
function($cx, $in) {return ''.((LCRun3::ifvar($cx,
((isset($in['actions']['undo']) && is_array($in['actions'])) ?
$in['actions']['undo'] : null))) ?
'<li>'.htmlentities((string)((isset($in['noop']) && is_array($in)) ?
$in['noop'] : null), ENT_QUOTES, 'UTF-8').'<a
class="'.htmlentities((string)((isset($in['moderationMwUiClass']) &&
is_array($in)) ? $in['moderationMwUiClass'] : null), ENT_QUOTES, 'UTF-8').'
mw-ui-quiet"
+
href="'.htmlentities((string)((isset($in['actions']['undo']['url']) &&
is_array($in['actions']['undo'])) ? $in['actions']['undo']['url'] : null),
ENT_QUOTES, 'UTF-8').'"
+
>'.htmlentities((string)((isset($in['actions']['undo']['title']) &&
is_array($in['actions']['undo'])) ? $in['actions']['undo']['title'] : null),
ENT_QUOTES, 'UTF-8').'</a>'.htmlentities((string)((isset($in['noop']) &&
is_array($in)) ? $in['noop'] : null), ENT_QUOTES, 'UTF-8').'</li>' :
'').'';}).''.((LCRun3::ifvar($cx, ((isset($in['actions']['hide']) &&
is_array($in['actions'])) ? $in['actions']['hide'] : null))) ?
'<li>'.htmlentities((string)((isset($in['noop']) && is_array($in)) ?
$in['noop'] : null), ENT_QUOTES, 'UTF-8').'<a
class="'.htmlentities((string)((isset($in['moderationMwUiClass']) &&
is_array($in)) ? $in['moderationMwUiClass'] : null), ENT_QUOTES, 'UTF-8').'
mw-ui-quiet"
href="'.htmlentities((string)((isset($in['actions']['hide']['url']) &&
is_array($in['actions']['hide'])) ? $in['actions']['hide']['url'] : null),
ENT_QUOTES, 'UTF-8').'"
title="'.htmlentities((string)((isset($in['actions']['hide']['title']) &&
is_array($in['actions']['hide'])) ? $in['actions']['hide']['title'] : null),
ENT_QUOTES, 'UTF-8').'"
data-flow-interactive-handler="moderationDialog"
diff --git a/handlebars/compiled/flow_block_topic_history.handlebars.php
b/handlebars/compiled/flow_block_topic_history.handlebars.php
index d2b5b0e..87b4272 100644
--- a/handlebars/compiled/flow_block_topic_history.handlebars.php
+++ b/handlebars/compiled/flow_block_topic_history.handlebars.php
@@ -41,7 +41,9 @@
href="'.htmlentities((string)((isset($in['links']['post']['url']) &&
is_array($in['links']['post'])) ? $in['links']['post']['url'] : null),
ENT_QUOTES, 'UTF-8').'"
title="'.htmlentities((string)((isset($in['links']['post']['title']) &&
is_array($in['links']['post'])) ? $in['links']['post']['title'] : null),
ENT_QUOTES, 'UTF-8').'">'.((LCRun3::ifvar($cx, ((isset($in['moderationIcons'])
&& is_array($in)) ? $in['moderationIcons'] : null))) ? '<span class="wikiglyph
wikiglyph-link"></span> ' : '').''.LCRun3::ch($cx, 'l10n',
array(array(LCRun3::ch($cx, 'concat',
array(array('flow-',((isset($in['moderationType']) && is_array($in)) ?
$in['moderationType'] : null),'-action-view'),array()), 'raw')),array()),
'encq').'</a>'.htmlentities((string)((isset($in['noop']) && is_array($in)) ?
$in['noop'] : null), ENT_QUOTES, 'UTF-8').'</li>' : '').'';}).'</section>
-<section>'.((LCRun3::ifvar($cx, ((isset($in['actions']['hide']) &&
is_array($in['actions'])) ? $in['actions']['hide'] : null))) ?
'<li>'.htmlentities((string)((isset($in['noop']) && is_array($in)) ?
$in['noop'] : null), ENT_QUOTES, 'UTF-8').'<a
class="'.htmlentities((string)((isset($in['moderationMwUiClass']) &&
is_array($in)) ? $in['moderationMwUiClass'] : null), ENT_QUOTES, 'UTF-8').'
mw-ui-quiet"
+<section>'.LCRun3::hbch($cx, 'ifCond',
array(array(((isset($in['moderationType']) && is_array($in)) ?
$in['moderationType'] : null),'===','history'),array()), $in, false,
function($cx, $in) {return ''.((LCRun3::ifvar($cx,
((isset($in['actions']['undo']) && is_array($in['actions'])) ?
$in['actions']['undo'] : null))) ?
'<li>'.htmlentities((string)((isset($in['noop']) && is_array($in)) ?
$in['noop'] : null), ENT_QUOTES, 'UTF-8').'<a
class="'.htmlentities((string)((isset($in['moderationMwUiClass']) &&
is_array($in)) ? $in['moderationMwUiClass'] : null), ENT_QUOTES, 'UTF-8').'
mw-ui-quiet"
+
href="'.htmlentities((string)((isset($in['actions']['undo']['url']) &&
is_array($in['actions']['undo'])) ? $in['actions']['undo']['url'] : null),
ENT_QUOTES, 'UTF-8').'"
+
>'.htmlentities((string)((isset($in['actions']['undo']['title']) &&
is_array($in['actions']['undo'])) ? $in['actions']['undo']['title'] : null),
ENT_QUOTES, 'UTF-8').'</a>'.htmlentities((string)((isset($in['noop']) &&
is_array($in)) ? $in['noop'] : null), ENT_QUOTES, 'UTF-8').'</li>' :
'').'';}).''.((LCRun3::ifvar($cx, ((isset($in['actions']['hide']) &&
is_array($in['actions'])) ? $in['actions']['hide'] : null))) ?
'<li>'.htmlentities((string)((isset($in['noop']) && is_array($in)) ?
$in['noop'] : null), ENT_QUOTES, 'UTF-8').'<a
class="'.htmlentities((string)((isset($in['moderationMwUiClass']) &&
is_array($in)) ? $in['moderationMwUiClass'] : null), ENT_QUOTES, 'UTF-8').'
mw-ui-quiet"
href="'.htmlentities((string)((isset($in['actions']['hide']['url']) &&
is_array($in['actions']['hide'])) ? $in['actions']['hide']['url'] : null),
ENT_QUOTES, 'UTF-8').'"
title="'.htmlentities((string)((isset($in['actions']['hide']['title']) &&
is_array($in['actions']['hide'])) ? $in['actions']['hide']['title'] : null),
ENT_QUOTES, 'UTF-8').'"
data-flow-interactive-handler="moderationDialog"
@@ -118,7 +120,6 @@
'.((LCRun3::ifvar($cx, ((isset($in['size']) && is_array($in)) ? $in['size'] :
null))) ? ' <span class="mw-changeslist-separator">. .</span>
'.LCRun3::ch($cx, 'showCharacterDifference',
array(array(((isset($in['size']['old']) && is_array($in['size'])) ?
$in['size']['old'] : null),((isset($in['size']['new']) &&
is_array($in['size'])) ? $in['size']['new'] : null)),array()), 'encq').'
' : '').'
-
<ul class="flow-history-moderation-menu">
'.LCRun3::p($cx, 'flow_moderation_actions_list',
array(array($in),array('moderationType'=>'history','moderationTarget'=>'post','moderationTemplate'=>'post','moderationMwUiClass'=>'mw-ui-anchor','moderationIcons'=>false))).'</ul>
';},),
diff --git a/handlebars/compiled/flow_block_topic_moderate_post.handlebars.php
b/handlebars/compiled/flow_block_topic_moderate_post.handlebars.php
index 4f05911..be7c659 100644
--- a/handlebars/compiled/flow_block_topic_moderate_post.handlebars.php
+++ b/handlebars/compiled/flow_block_topic_moderate_post.handlebars.php
@@ -120,7 +120,9 @@
href="'.htmlentities((string)((isset($in['links']['post']['url']) &&
is_array($in['links']['post'])) ? $in['links']['post']['url'] : null),
ENT_QUOTES, 'UTF-8').'"
title="'.htmlentities((string)((isset($in['links']['post']['title']) &&
is_array($in['links']['post'])) ? $in['links']['post']['title'] : null),
ENT_QUOTES, 'UTF-8').'">'.((LCRun3::ifvar($cx, ((isset($in['moderationIcons'])
&& is_array($in)) ? $in['moderationIcons'] : null))) ? '<span class="wikiglyph
wikiglyph-link"></span> ' : '').''.LCRun3::ch($cx, 'l10n',
array(array(LCRun3::ch($cx, 'concat',
array(array('flow-',((isset($in['moderationType']) && is_array($in)) ?
$in['moderationType'] : null),'-action-view'),array()), 'raw')),array()),
'encq').'</a>'.htmlentities((string)((isset($in['noop']) && is_array($in)) ?
$in['noop'] : null), ENT_QUOTES, 'UTF-8').'</li>' : '').'';}).'</section>
-<section>'.((LCRun3::ifvar($cx, ((isset($in['actions']['hide']) &&
is_array($in['actions'])) ? $in['actions']['hide'] : null))) ?
'<li>'.htmlentities((string)((isset($in['noop']) && is_array($in)) ?
$in['noop'] : null), ENT_QUOTES, 'UTF-8').'<a
class="'.htmlentities((string)((isset($in['moderationMwUiClass']) &&
is_array($in)) ? $in['moderationMwUiClass'] : null), ENT_QUOTES, 'UTF-8').'
mw-ui-quiet"
+<section>'.LCRun3::hbch($cx, 'ifCond',
array(array(((isset($in['moderationType']) && is_array($in)) ?
$in['moderationType'] : null),'===','history'),array()), $in, false,
function($cx, $in) {return ''.((LCRun3::ifvar($cx,
((isset($in['actions']['undo']) && is_array($in['actions'])) ?
$in['actions']['undo'] : null))) ?
'<li>'.htmlentities((string)((isset($in['noop']) && is_array($in)) ?
$in['noop'] : null), ENT_QUOTES, 'UTF-8').'<a
class="'.htmlentities((string)((isset($in['moderationMwUiClass']) &&
is_array($in)) ? $in['moderationMwUiClass'] : null), ENT_QUOTES, 'UTF-8').'
mw-ui-quiet"
+
href="'.htmlentities((string)((isset($in['actions']['undo']['url']) &&
is_array($in['actions']['undo'])) ? $in['actions']['undo']['url'] : null),
ENT_QUOTES, 'UTF-8').'"
+
>'.htmlentities((string)((isset($in['actions']['undo']['title']) &&
is_array($in['actions']['undo'])) ? $in['actions']['undo']['title'] : null),
ENT_QUOTES, 'UTF-8').'</a>'.htmlentities((string)((isset($in['noop']) &&
is_array($in)) ? $in['noop'] : null), ENT_QUOTES, 'UTF-8').'</li>' :
'').'';}).''.((LCRun3::ifvar($cx, ((isset($in['actions']['hide']) &&
is_array($in['actions'])) ? $in['actions']['hide'] : null))) ?
'<li>'.htmlentities((string)((isset($in['noop']) && is_array($in)) ?
$in['noop'] : null), ENT_QUOTES, 'UTF-8').'<a
class="'.htmlentities((string)((isset($in['moderationMwUiClass']) &&
is_array($in)) ? $in['moderationMwUiClass'] : null), ENT_QUOTES, 'UTF-8').'
mw-ui-quiet"
href="'.htmlentities((string)((isset($in['actions']['hide']['url']) &&
is_array($in['actions']['hide'])) ? $in['actions']['hide']['url'] : null),
ENT_QUOTES, 'UTF-8').'"
title="'.htmlentities((string)((isset($in['actions']['hide']['title']) &&
is_array($in['actions']['hide'])) ? $in['actions']['hide']['title'] : null),
ENT_QUOTES, 'UTF-8').'"
data-flow-interactive-handler="moderationDialog"
@@ -235,6 +237,7 @@
<textarea name="topic_content" class="mw-ui-input flow-form-collapsible"
data-flow-preview-template="flow_post"
data-flow-preview-title="'.htmlentities((string)((isset($in['articleTitle']) &&
is_array($in)) ? $in['articleTitle'] : null), ENT_QUOTES, 'UTF-8').'"
+
data-flow-creator="'.htmlentities((string)((isset($in['creator']['name']) &&
is_array($in['creator'])) ? $in['creator']['name'] : null), ENT_QUOTES,
'UTF-8').'"
data-role="content">'.((LCRun3::ifvar($cx,
((isset($cx['sp_vars']['root']['rootBlock']['submitted']['content']) &&
is_array($cx['sp_vars']['root']['rootBlock']['submitted'])) ?
$cx['sp_vars']['root']['rootBlock']['submitted']['content'] : null))) ?
''.htmlentities((string)((isset($cx['sp_vars']['root']['rootBlock']['submitted']['content'])
&& is_array($cx['sp_vars']['root']['rootBlock']['submitted'])) ?
$cx['sp_vars']['root']['rootBlock']['submitted']['content'] : null),
ENT_QUOTES, 'UTF-8').'' :
''.htmlentities((string)((isset($in['content']['content']) &&
is_array($in['content'])) ? $in['content']['content'] : null), ENT_QUOTES,
'UTF-8').'').'</textarea>
<div class="flow-form-actions flow-form-collapsible">
diff --git a/handlebars/compiled/flow_block_topic_moderate_topic.handlebars.php
b/handlebars/compiled/flow_block_topic_moderate_topic.handlebars.php
index 661fb2d..861e441 100644
--- a/handlebars/compiled/flow_block_topic_moderate_topic.handlebars.php
+++ b/handlebars/compiled/flow_block_topic_moderate_topic.handlebars.php
@@ -120,7 +120,9 @@
href="'.htmlentities((string)((isset($in['links']['post']['url']) &&
is_array($in['links']['post'])) ? $in['links']['post']['url'] : null),
ENT_QUOTES, 'UTF-8').'"
title="'.htmlentities((string)((isset($in['links']['post']['title']) &&
is_array($in['links']['post'])) ? $in['links']['post']['title'] : null),
ENT_QUOTES, 'UTF-8').'">'.((LCRun3::ifvar($cx, ((isset($in['moderationIcons'])
&& is_array($in)) ? $in['moderationIcons'] : null))) ? '<span class="wikiglyph
wikiglyph-link"></span> ' : '').''.LCRun3::ch($cx, 'l10n',
array(array(LCRun3::ch($cx, 'concat',
array(array('flow-',((isset($in['moderationType']) && is_array($in)) ?
$in['moderationType'] : null),'-action-view'),array()), 'raw')),array()),
'encq').'</a>'.htmlentities((string)((isset($in['noop']) && is_array($in)) ?
$in['noop'] : null), ENT_QUOTES, 'UTF-8').'</li>' : '').'';}).'</section>
-<section>'.((LCRun3::ifvar($cx, ((isset($in['actions']['hide']) &&
is_array($in['actions'])) ? $in['actions']['hide'] : null))) ?
'<li>'.htmlentities((string)((isset($in['noop']) && is_array($in)) ?
$in['noop'] : null), ENT_QUOTES, 'UTF-8').'<a
class="'.htmlentities((string)((isset($in['moderationMwUiClass']) &&
is_array($in)) ? $in['moderationMwUiClass'] : null), ENT_QUOTES, 'UTF-8').'
mw-ui-quiet"
+<section>'.LCRun3::hbch($cx, 'ifCond',
array(array(((isset($in['moderationType']) && is_array($in)) ?
$in['moderationType'] : null),'===','history'),array()), $in, false,
function($cx, $in) {return ''.((LCRun3::ifvar($cx,
((isset($in['actions']['undo']) && is_array($in['actions'])) ?
$in['actions']['undo'] : null))) ?
'<li>'.htmlentities((string)((isset($in['noop']) && is_array($in)) ?
$in['noop'] : null), ENT_QUOTES, 'UTF-8').'<a
class="'.htmlentities((string)((isset($in['moderationMwUiClass']) &&
is_array($in)) ? $in['moderationMwUiClass'] : null), ENT_QUOTES, 'UTF-8').'
mw-ui-quiet"
+
href="'.htmlentities((string)((isset($in['actions']['undo']['url']) &&
is_array($in['actions']['undo'])) ? $in['actions']['undo']['url'] : null),
ENT_QUOTES, 'UTF-8').'"
+
>'.htmlentities((string)((isset($in['actions']['undo']['title']) &&
is_array($in['actions']['undo'])) ? $in['actions']['undo']['title'] : null),
ENT_QUOTES, 'UTF-8').'</a>'.htmlentities((string)((isset($in['noop']) &&
is_array($in)) ? $in['noop'] : null), ENT_QUOTES, 'UTF-8').'</li>' :
'').'';}).''.((LCRun3::ifvar($cx, ((isset($in['actions']['hide']) &&
is_array($in['actions'])) ? $in['actions']['hide'] : null))) ?
'<li>'.htmlentities((string)((isset($in['noop']) && is_array($in)) ?
$in['noop'] : null), ENT_QUOTES, 'UTF-8').'<a
class="'.htmlentities((string)((isset($in['moderationMwUiClass']) &&
is_array($in)) ? $in['moderationMwUiClass'] : null), ENT_QUOTES, 'UTF-8').'
mw-ui-quiet"
href="'.htmlentities((string)((isset($in['actions']['hide']['url']) &&
is_array($in['actions']['hide'])) ? $in['actions']['hide']['url'] : null),
ENT_QUOTES, 'UTF-8').'"
title="'.htmlentities((string)((isset($in['actions']['hide']['title']) &&
is_array($in['actions']['hide'])) ? $in['actions']['hide']['title'] : null),
ENT_QUOTES, 'UTF-8').'"
data-flow-interactive-handler="moderationDialog"
@@ -235,6 +237,7 @@
<textarea name="topic_content" class="mw-ui-input flow-form-collapsible"
data-flow-preview-template="flow_post"
data-flow-preview-title="'.htmlentities((string)((isset($in['articleTitle']) &&
is_array($in)) ? $in['articleTitle'] : null), ENT_QUOTES, 'UTF-8').'"
+
data-flow-creator="'.htmlentities((string)((isset($in['creator']['name']) &&
is_array($in['creator'])) ? $in['creator']['name'] : null), ENT_QUOTES,
'UTF-8').'"
data-role="content">'.((LCRun3::ifvar($cx,
((isset($cx['sp_vars']['root']['rootBlock']['submitted']['content']) &&
is_array($cx['sp_vars']['root']['rootBlock']['submitted'])) ?
$cx['sp_vars']['root']['rootBlock']['submitted']['content'] : null))) ?
''.htmlentities((string)((isset($cx['sp_vars']['root']['rootBlock']['submitted']['content'])
&& is_array($cx['sp_vars']['root']['rootBlock']['submitted'])) ?
$cx['sp_vars']['root']['rootBlock']['submitted']['content'] : null),
ENT_QUOTES, 'UTF-8').'' :
''.htmlentities((string)((isset($in['content']['content']) &&
is_array($in['content'])) ? $in['content']['content'] : null), ENT_QUOTES,
'UTF-8').'').'</textarea>
<div class="flow-form-actions flow-form-collapsible">
diff --git a/handlebars/compiled/flow_block_topic_undo_edit.handlebars.php
b/handlebars/compiled/flow_block_topic_undo_edit.handlebars.php
new file mode 100644
index 0000000..68b9f28
--- /dev/null
+++ b/handlebars/compiled/flow_block_topic_undo_edit.handlebars.php
@@ -0,0 +1,79 @@
+<?php return function ($in, $debugopt = 1) {
+ $cx = array(
+ 'flags' => array(
+ 'jstrue' => false,
+ 'jsobj' => false,
+ 'spvar' => true,
+ 'prop' => false,
+ 'method' => false,
+ 'mustlok' => false,
+ 'mustsec' => false,
+ 'echo' => false,
+ 'debug' => $debugopt,
+ ),
+ 'constants' => array(),
+ 'helpers' => array( 'l10n' => 'Flow\TemplateHelper::l10n',
+ 'html' => 'Flow\TemplateHelper::htmlHelper',
+ 'l10nParse' => 'Flow\TemplateHelper::l10nParse',
+ 'diffUndo' => 'Flow\TemplateHelper::diffUndo',
+),
+ 'blockhelpers' => array(),
+ 'hbhelpers' => array(),
+ 'partials' => array('flow_errors' => function ($cx, $in) {return '<div
class="flow-error-container">
+'.((LCRun3::ifvar($cx, ((isset($cx['sp_vars']['root']['errors']) &&
is_array($cx['sp_vars']['root'])) ? $cx['sp_vars']['root']['errors'] : null)))
? ' <div class="flow-errors errorbox">
+ <ul>
+'.LCRun3::sec($cx, ((isset($cx['sp_vars']['root']['errors']) &&
is_array($cx['sp_vars']['root'])) ? $cx['sp_vars']['root']['errors'] : null),
$in, true, function($cx, $in) {return '
<li>'.LCRun3::ch($cx, 'html', array(array(((isset($in['message']) &&
is_array($in)) ? $in['message'] : null)),array()), 'encq').'</li>
+';}).' </ul>
+ </div>
+' : '').'</div>
+';},'flow_form_buttons' => function ($cx, $in) {return '<button
data-flow-api-handler="preview"
+ data-flow-api-target="< form textarea"
+ name="preview"
+ data-role="action"
+ class="mw-ui-button mw-ui-progressive mw-ui-quiet mw-ui-flush-right
flow-form-action-preview flow-js"
+
+>'.LCRun3::ch($cx, 'l10n', array(array('flow-preview'),array()),
'encq').'</button>
+
+<button data-flow-interactive-handler="cancelForm"
+ data-role="cancel"
+ type="reset"
+ class="mw-ui-button mw-ui-destructive mw-ui-quiet mw-ui-flush-right
flow-js"
+
+>'.LCRun3::ch($cx, 'l10n', array(array('flow-cancel'),array()),
'encq').'</button>
+';},),
+ 'scopes' => array($in),
+ 'sp_vars' => array('root' => $in),
+
+ );
+
+ return '<div class="flow-board">
+'.((LCRun3::ifvar($cx, ((isset($in['undo']['possible']) &&
is_array($in['undo'])) ? $in['undo']['possible'] : null))) ? '
<p>'.LCRun3::ch($cx, 'l10n', array(array('flow-undo-edit-content'),array()),
'encq').'</p>
+' : ' <p class="error">'.LCRun3::ch($cx, 'l10n',
array(array('flow-undo-edit-failure'),array()), 'encq').'</p>
+').'
+'.LCRun3::p($cx, 'flow_errors', array(array($in),array())).'
+'.((LCRun3::ifvar($cx, ((isset($in['undo']['possible']) &&
is_array($in['undo'])) ? $in['undo']['possible'] : null))) ? '
'.LCRun3::ch($cx, 'diffUndo', array(array(((isset($in['undo']['diff_content'])
&& is_array($in['undo'])) ? $in['undo']['diff_content'] : null)),array()),
'encq').'
+' : '').'
+ <form method="POST"
action="'.htmlentities((string)((isset($in['links']['undo-edit-post']['url'])
&& is_array($in['links']['undo-edit-post'])) ?
$in['links']['undo-edit-post']['url'] : null), ENT_QUOTES, 'UTF-8').'"
class="flow-post">
+ <input type="hidden" name="wpEditToken"
value="'.htmlentities((string)((isset($cx['sp_vars']['root']['rootBlock']['editToken'])
&& is_array($cx['sp_vars']['root']['rootBlock'])) ?
$cx['sp_vars']['root']['rootBlock']['editToken'] : null), ENT_QUOTES,
'UTF-8').'" />
+ <input type="hidden" name="topic_prev_revision"
value="'.htmlentities((string)((isset($in['current']['revisionId']) &&
is_array($in['current'])) ? $in['current']['revisionId'] : null), ENT_QUOTES,
'UTF-8').'" />
+ <input type="hidden" name="topic_postId"
value="'.htmlentities((string)((isset($in['current']['postId']) &&
is_array($in['current'])) ? $in['current']['postId'] : null), ENT_QUOTES,
'UTF-8').'" />
+
+ <textarea name="topic_content"
+ class="mw-ui-input"
+ data-role="content"
+ data-flow-preview-template="flow_post"
+
data-flow-preview-title="'.htmlentities((string)((isset($in['articleTitle']) &&
is_array($in)) ? $in['articleTitle'] : null), ENT_QUOTES, 'UTF-8').'"
+
data-flow-username="'.htmlentities((string)((isset($in['current']['creator']['name'])
&& is_array($in['current']['creator'])) ? $in['current']['creator']['name'] :
null), ENT_QUOTES, 'UTF-8').'"
+ >'.((LCRun3::ifvar($cx, ((isset($in['submitted']['content']) &&
is_array($in['submitted'])) ? $in['submitted']['content'] : null))) ?
''.htmlentities((string)((isset($in['submitted']['content']) &&
is_array($in['submitted'])) ? $in['submitted']['content'] : null), ENT_QUOTES,
'UTF-8').'' : ''.((LCRun3::ifvar($cx, ((isset($in['undo']['possible']) &&
is_array($in['undo'])) ? $in['undo']['possible'] : null))) ?
''.htmlentities((string)((isset($in['undo']['content']) &&
is_array($in['undo'])) ? $in['undo']['content'] : null), ENT_QUOTES,
'UTF-8').'' :
''.htmlentities((string)((isset($in['current']['content']['content']) &&
is_array($in['current']['content'])) ? $in['current']['content']['content'] :
null), ENT_QUOTES, 'UTF-8').'').'').'</textarea>
+
+ <div class="flow-form-actions flow-form-collapsible">
+ <button class="mw-ui-button
mw-ui-constructive">'.LCRun3::ch($cx, 'l10n',
array(array('flow-edit-post-submit'),array()), 'encq').'</button>
+'.LCRun3::p($cx, 'flow_form_buttons', array(array($in),array())).'
<small class="flow-terms-of-use plainlinks">'.LCRun3::ch($cx,
'l10nParse', array(array('flow-terms-of-use-edit'),array()), 'encq').'
+ </small>
+ </div>
+ </form>
+</div>
+
+';
+}
+?>
\ No newline at end of file
diff --git a/handlebars/compiled/flow_block_topiclist.handlebars.php
b/handlebars/compiled/flow_block_topiclist.handlebars.php
index cf2ab0e..65eac7e 100644
--- a/handlebars/compiled/flow_block_topiclist.handlebars.php
+++ b/handlebars/compiled/flow_block_topiclist.handlebars.php
@@ -199,7 +199,9 @@
href="'.htmlentities((string)((isset($in['links']['post']['url']) &&
is_array($in['links']['post'])) ? $in['links']['post']['url'] : null),
ENT_QUOTES, 'UTF-8').'"
title="'.htmlentities((string)((isset($in['links']['post']['title']) &&
is_array($in['links']['post'])) ? $in['links']['post']['title'] : null),
ENT_QUOTES, 'UTF-8').'">'.((LCRun3::ifvar($cx, ((isset($in['moderationIcons'])
&& is_array($in)) ? $in['moderationIcons'] : null))) ? '<span class="wikiglyph
wikiglyph-link"></span> ' : '').''.LCRun3::ch($cx, 'l10n',
array(array(LCRun3::ch($cx, 'concat',
array(array('flow-',((isset($in['moderationType']) && is_array($in)) ?
$in['moderationType'] : null),'-action-view'),array()), 'raw')),array()),
'encq').'</a>'.htmlentities((string)((isset($in['noop']) && is_array($in)) ?
$in['noop'] : null), ENT_QUOTES, 'UTF-8').'</li>' : '').'';}).'</section>
-<section>'.((LCRun3::ifvar($cx, ((isset($in['actions']['hide']) &&
is_array($in['actions'])) ? $in['actions']['hide'] : null))) ?
'<li>'.htmlentities((string)((isset($in['noop']) && is_array($in)) ?
$in['noop'] : null), ENT_QUOTES, 'UTF-8').'<a
class="'.htmlentities((string)((isset($in['moderationMwUiClass']) &&
is_array($in)) ? $in['moderationMwUiClass'] : null), ENT_QUOTES, 'UTF-8').'
mw-ui-quiet"
+<section>'.LCRun3::hbch($cx, 'ifCond',
array(array(((isset($in['moderationType']) && is_array($in)) ?
$in['moderationType'] : null),'===','history'),array()), $in, false,
function($cx, $in) {return ''.((LCRun3::ifvar($cx,
((isset($in['actions']['undo']) && is_array($in['actions'])) ?
$in['actions']['undo'] : null))) ?
'<li>'.htmlentities((string)((isset($in['noop']) && is_array($in)) ?
$in['noop'] : null), ENT_QUOTES, 'UTF-8').'<a
class="'.htmlentities((string)((isset($in['moderationMwUiClass']) &&
is_array($in)) ? $in['moderationMwUiClass'] : null), ENT_QUOTES, 'UTF-8').'
mw-ui-quiet"
+
href="'.htmlentities((string)((isset($in['actions']['undo']['url']) &&
is_array($in['actions']['undo'])) ? $in['actions']['undo']['url'] : null),
ENT_QUOTES, 'UTF-8').'"
+
>'.htmlentities((string)((isset($in['actions']['undo']['title']) &&
is_array($in['actions']['undo'])) ? $in['actions']['undo']['title'] : null),
ENT_QUOTES, 'UTF-8').'</a>'.htmlentities((string)((isset($in['noop']) &&
is_array($in)) ? $in['noop'] : null), ENT_QUOTES, 'UTF-8').'</li>' :
'').'';}).''.((LCRun3::ifvar($cx, ((isset($in['actions']['hide']) &&
is_array($in['actions'])) ? $in['actions']['hide'] : null))) ?
'<li>'.htmlentities((string)((isset($in['noop']) && is_array($in)) ?
$in['noop'] : null), ENT_QUOTES, 'UTF-8').'<a
class="'.htmlentities((string)((isset($in['moderationMwUiClass']) &&
is_array($in)) ? $in['moderationMwUiClass'] : null), ENT_QUOTES, 'UTF-8').'
mw-ui-quiet"
href="'.htmlentities((string)((isset($in['actions']['hide']['url']) &&
is_array($in['actions']['hide'])) ? $in['actions']['hide']['url'] : null),
ENT_QUOTES, 'UTF-8').'"
title="'.htmlentities((string)((isset($in['actions']['hide']['title']) &&
is_array($in['actions']['hide'])) ? $in['actions']['hide']['title'] : null),
ENT_QUOTES, 'UTF-8').'"
data-flow-interactive-handler="moderationDialog"
diff --git
a/handlebars/compiled/flow_block_topicsummary_undo_edit.handlebars.php
b/handlebars/compiled/flow_block_topicsummary_undo_edit.handlebars.php
new file mode 100644
index 0000000..186df81
--- /dev/null
+++ b/handlebars/compiled/flow_block_topicsummary_undo_edit.handlebars.php
@@ -0,0 +1,78 @@
+<?php return function ($in, $debugopt = 1) {
+ $cx = array(
+ 'flags' => array(
+ 'jstrue' => false,
+ 'jsobj' => false,
+ 'spvar' => true,
+ 'prop' => false,
+ 'method' => false,
+ 'mustlok' => false,
+ 'mustsec' => false,
+ 'echo' => false,
+ 'debug' => $debugopt,
+ ),
+ 'constants' => array(),
+ 'helpers' => array( 'l10n' => 'Flow\TemplateHelper::l10n',
+ 'html' => 'Flow\TemplateHelper::htmlHelper',
+ 'l10nParse' => 'Flow\TemplateHelper::l10nParse',
+ 'diffUndo' => 'Flow\TemplateHelper::diffUndo',
+),
+ 'blockhelpers' => array(),
+ 'hbhelpers' => array(),
+ 'partials' => array('flow_errors' => function ($cx, $in) {return '<div
class="flow-error-container">
+'.((LCRun3::ifvar($cx, ((isset($cx['sp_vars']['root']['errors']) &&
is_array($cx['sp_vars']['root'])) ? $cx['sp_vars']['root']['errors'] : null)))
? ' <div class="flow-errors errorbox">
+ <ul>
+'.LCRun3::sec($cx, ((isset($cx['sp_vars']['root']['errors']) &&
is_array($cx['sp_vars']['root'])) ? $cx['sp_vars']['root']['errors'] : null),
$in, true, function($cx, $in) {return '
<li>'.LCRun3::ch($cx, 'html', array(array(((isset($in['message']) &&
is_array($in)) ? $in['message'] : null)),array()), 'encq').'</li>
+';}).' </ul>
+ </div>
+' : '').'</div>
+';},'flow_form_buttons' => function ($cx, $in) {return '<button
data-flow-api-handler="preview"
+ data-flow-api-target="< form textarea"
+ name="preview"
+ data-role="action"
+ class="mw-ui-button mw-ui-progressive mw-ui-quiet mw-ui-flush-right
flow-form-action-preview flow-js"
+
+>'.LCRun3::ch($cx, 'l10n', array(array('flow-preview'),array()),
'encq').'</button>
+
+<button data-flow-interactive-handler="cancelForm"
+ data-role="cancel"
+ type="reset"
+ class="mw-ui-button mw-ui-destructive mw-ui-quiet mw-ui-flush-right
flow-js"
+
+>'.LCRun3::ch($cx, 'l10n', array(array('flow-cancel'),array()),
'encq').'</button>
+';},),
+ 'scopes' => array($in),
+ 'sp_vars' => array('root' => $in),
+
+ );
+
+ return '<div class="flow-board">
+'.((LCRun3::ifvar($cx, ((isset($in['undo']['possible']) &&
is_array($in['undo'])) ? $in['undo']['possible'] : null))) ? '
<p>'.LCRun3::ch($cx, 'l10n', array(array('flow-undo-edit-content'),array()),
'encq').'</p>
+' : ' <p class="error">'.LCRun3::ch($cx, 'l10n',
array(array('flow-undo-edit-failure'),array()), 'encq').'</p>
+').'
+'.LCRun3::p($cx, 'flow_errors', array(array($in),array())).'
+'.((LCRun3::ifvar($cx, ((isset($in['undo']['possible']) &&
is_array($in['undo'])) ? $in['undo']['possible'] : null))) ? '
'.LCRun3::ch($cx, 'diffUndo', array(array(((isset($in['undo']['diff_content'])
&& is_array($in['undo'])) ? $in['undo']['diff_content'] : null)),array()),
'encq').'
+' : '').'
+ <form method="POST"
action="'.htmlentities((string)((isset($in['links']['undo-edit-header']['url'])
&& is_array($in['links']['undo-edit-header'])) ?
$in['links']['undo-edit-header']['url'] : null), ENT_QUOTES, 'UTF-8').'"
class="flow-post">
+ <input type="hidden" name="wpEditToken"
value="'.htmlentities((string)((isset($cx['sp_vars']['root']['rootBlock']['editToken'])
&& is_array($cx['sp_vars']['root']['rootBlock'])) ?
$cx['sp_vars']['root']['rootBlock']['editToken'] : null), ENT_QUOTES,
'UTF-8').'" />
+ <input type="hidden" name="topicsummary_prev_revision"
value="'.htmlentities((string)((isset($in['current']['revisionId']) &&
is_array($in['current'])) ? $in['current']['revisionId'] : null), ENT_QUOTES,
'UTF-8').'" />
+
+ <textarea name="topicsummary_summary"
+ class="mw-ui-input"
+ data-role="content"
+ data-flow-preview-node="summary"
+
data-flow-preview-template="flow_topic_titlebar_summary.partial"
+
data-flow-preview-title="'.htmlentities((string)((isset($in['articleTitle']) &&
is_array($in)) ? $in['articleTitle'] : null), ENT_QUOTES, 'UTF-8').'"
+ >'.((LCRun3::ifvar($cx, ((isset($in['submitted']['content']) &&
is_array($in['submitted'])) ? $in['submitted']['content'] : null))) ?
''.htmlentities((string)((isset($in['submitted']['content']) &&
is_array($in['submitted'])) ? $in['submitted']['content'] : null), ENT_QUOTES,
'UTF-8').'' : ''.((LCRun3::ifvar($cx, ((isset($in['undo']['possible']) &&
is_array($in['undo'])) ? $in['undo']['possible'] : null))) ?
''.htmlentities((string)((isset($in['undo']['content']) &&
is_array($in['undo'])) ? $in['undo']['content'] : null), ENT_QUOTES,
'UTF-8').'' :
''.htmlentities((string)((isset($in['current']['content']['content']) &&
is_array($in['current']['content'])) ? $in['current']['content']['content'] :
null), ENT_QUOTES, 'UTF-8').'').'').'</textarea>
+
+ <div class="flow-form-actions flow-form-collapsible">
+ <button class="mw-ui-button
mw-ui-constructive">'.LCRun3::ch($cx, 'l10n',
array(array('flow-topic-action-summarize-topic'),array()), 'encq').'</button>
+'.LCRun3::p($cx, 'flow_form_buttons', array(array($in),array())).'
<small class="flow-terms-of-use plainlinks">'.LCRun3::ch($cx,
'l10nParse', array(array('flow-terms-of-use-summarize'),array()), 'encq').'
+ </small>
+ </div>
+ </form>
+</div>
+
+';
+}
+?>
\ No newline at end of file
diff --git a/handlebars/compiled/flow_post.handlebars.php
b/handlebars/compiled/flow_post.handlebars.php
index 7a4f229..18b250d 100644
--- a/handlebars/compiled/flow_post.handlebars.php
+++ b/handlebars/compiled/flow_post.handlebars.php
@@ -99,7 +99,9 @@
href="'.htmlentities((string)((isset($in['links']['post']['url']) &&
is_array($in['links']['post'])) ? $in['links']['post']['url'] : null),
ENT_QUOTES, 'UTF-8').'"
title="'.htmlentities((string)((isset($in['links']['post']['title']) &&
is_array($in['links']['post'])) ? $in['links']['post']['title'] : null),
ENT_QUOTES, 'UTF-8').'">'.((LCRun3::ifvar($cx, ((isset($in['moderationIcons'])
&& is_array($in)) ? $in['moderationIcons'] : null))) ? '<span class="wikiglyph
wikiglyph-link"></span> ' : '').''.LCRun3::ch($cx, 'l10n',
array(array(LCRun3::ch($cx, 'concat',
array(array('flow-',((isset($in['moderationType']) && is_array($in)) ?
$in['moderationType'] : null),'-action-view'),array()), 'raw')),array()),
'encq').'</a>'.htmlentities((string)((isset($in['noop']) && is_array($in)) ?
$in['noop'] : null), ENT_QUOTES, 'UTF-8').'</li>' : '').'';}).'</section>
-<section>'.((LCRun3::ifvar($cx, ((isset($in['actions']['hide']) &&
is_array($in['actions'])) ? $in['actions']['hide'] : null))) ?
'<li>'.htmlentities((string)((isset($in['noop']) && is_array($in)) ?
$in['noop'] : null), ENT_QUOTES, 'UTF-8').'<a
class="'.htmlentities((string)((isset($in['moderationMwUiClass']) &&
is_array($in)) ? $in['moderationMwUiClass'] : null), ENT_QUOTES, 'UTF-8').'
mw-ui-quiet"
+<section>'.LCRun3::hbch($cx, 'ifCond',
array(array(((isset($in['moderationType']) && is_array($in)) ?
$in['moderationType'] : null),'===','history'),array()), $in, false,
function($cx, $in) {return ''.((LCRun3::ifvar($cx,
((isset($in['actions']['undo']) && is_array($in['actions'])) ?
$in['actions']['undo'] : null))) ?
'<li>'.htmlentities((string)((isset($in['noop']) && is_array($in)) ?
$in['noop'] : null), ENT_QUOTES, 'UTF-8').'<a
class="'.htmlentities((string)((isset($in['moderationMwUiClass']) &&
is_array($in)) ? $in['moderationMwUiClass'] : null), ENT_QUOTES, 'UTF-8').'
mw-ui-quiet"
+
href="'.htmlentities((string)((isset($in['actions']['undo']['url']) &&
is_array($in['actions']['undo'])) ? $in['actions']['undo']['url'] : null),
ENT_QUOTES, 'UTF-8').'"
+
>'.htmlentities((string)((isset($in['actions']['undo']['title']) &&
is_array($in['actions']['undo'])) ? $in['actions']['undo']['title'] : null),
ENT_QUOTES, 'UTF-8').'</a>'.htmlentities((string)((isset($in['noop']) &&
is_array($in)) ? $in['noop'] : null), ENT_QUOTES, 'UTF-8').'</li>' :
'').'';}).''.((LCRun3::ifvar($cx, ((isset($in['actions']['hide']) &&
is_array($in['actions'])) ? $in['actions']['hide'] : null))) ?
'<li>'.htmlentities((string)((isset($in['noop']) && is_array($in)) ?
$in['noop'] : null), ENT_QUOTES, 'UTF-8').'<a
class="'.htmlentities((string)((isset($in['moderationMwUiClass']) &&
is_array($in)) ? $in['moderationMwUiClass'] : null), ENT_QUOTES, 'UTF-8').'
mw-ui-quiet"
href="'.htmlentities((string)((isset($in['actions']['hide']['url']) &&
is_array($in['actions']['hide'])) ? $in['actions']['hide']['url'] : null),
ENT_QUOTES, 'UTF-8').'"
title="'.htmlentities((string)((isset($in['actions']['hide']['title']) &&
is_array($in['actions']['hide'])) ? $in['actions']['hide']['title'] : null),
ENT_QUOTES, 'UTF-8').'"
data-flow-interactive-handler="moderationDialog"
@@ -214,6 +216,7 @@
<textarea name="topic_content" class="mw-ui-input flow-form-collapsible"
data-flow-preview-template="flow_post"
data-flow-preview-title="'.htmlentities((string)((isset($in['articleTitle']) &&
is_array($in)) ? $in['articleTitle'] : null), ENT_QUOTES, 'UTF-8').'"
+
data-flow-creator="'.htmlentities((string)((isset($in['creator']['name']) &&
is_array($in['creator'])) ? $in['creator']['name'] : null), ENT_QUOTES,
'UTF-8').'"
data-role="content">'.((LCRun3::ifvar($cx,
((isset($cx['sp_vars']['root']['rootBlock']['submitted']['content']) &&
is_array($cx['sp_vars']['root']['rootBlock']['submitted'])) ?
$cx['sp_vars']['root']['rootBlock']['submitted']['content'] : null))) ?
''.htmlentities((string)((isset($cx['sp_vars']['root']['rootBlock']['submitted']['content'])
&& is_array($cx['sp_vars']['root']['rootBlock']['submitted'])) ?
$cx['sp_vars']['root']['rootBlock']['submitted']['content'] : null),
ENT_QUOTES, 'UTF-8').'' :
''.htmlentities((string)((isset($in['content']['content']) &&
is_array($in['content'])) ? $in['content']['content'] : null), ENT_QUOTES,
'UTF-8').'').'</textarea>
<div class="flow-form-actions flow-form-collapsible">
diff --git a/handlebars/flow_block_header_undo_edit.handlebars
b/handlebars/flow_block_header_undo_edit.handlebars
new file mode 100644
index 0000000..f469ddf
--- /dev/null
+++ b/handlebars/flow_block_header_undo_edit.handlebars
@@ -0,0 +1,46 @@
+<div class="flow-board">
+ {{#if undo.possible}}
+ <p>{{l10n "flow-undo-edit-content"}}</p>
+ {{else}}
+ <p class="error">{{l10n "flow-undo-edit-failure"}}</p>
+ {{/if}}
+
+ {{> flow_errors}}
+
+ {{#if undo.possible}}
+ {{diffUndo undo.diff_content}}
+ {{/if}}
+
+ <form method="POST" action="{{links.undo-edit-header.url}}"
class="flow-post">
+ <input type="hidden" name="wpEditToken"
value="{{@root.rootBlock.editToken}}" />
+ <input type="hidden" name="header_prev_revision"
value="{{current.revisionId}}" />
+
+ <textarea name="topic_content"
+ class="mw-ui-input"
+ data-role="content"
+
data-flow-preview-template="flow_header_detail.partial"
+ data-flow-preview-title="{{articleTitle}}"
+ >
+ {{~#if submitted.content~}}
+ {{~submitted.content~}}
+ {{~else~}}
+ {{~#if undo.possible~}}
+ {{~undo.content~}}
+ {{~else~}}
+ {{~current.content.content~}}
+ {{~/if~}}
+ {{~/if~}}
+ </textarea>
+
+ <div class="flow-form-actions flow-form-collapsible">
+ <button class="mw-ui-button mw-ui-constructive">
+ {{~l10n "flow-edit-header-submit"~}}
+ </button>
+ {{> flow_form_buttons}}
+ <small class="flow-terms-of-use plainlinks">
+ {{~l10nParse "flow-terms-of-use-edit"}}
+ </small>
+ </div>
+ </form>
+</div>
+
diff --git a/handlebars/flow_block_topic_undo_edit.handlebars
b/handlebars/flow_block_topic_undo_edit.handlebars
new file mode 100644
index 0000000..860c475
--- /dev/null
+++ b/handlebars/flow_block_topic_undo_edit.handlebars
@@ -0,0 +1,48 @@
+<div class="flow-board">
+ {{#if undo.possible}}
+ <p>{{l10n "flow-undo-edit-content"}}</p>
+ {{else}}
+ <p class="error">{{l10n "flow-undo-edit-failure"}}</p>
+ {{/if}}
+
+ {{> flow_errors}}
+
+ {{#if undo.possible}}
+ {{diffUndo undo.diff_content}}
+ {{/if}}
+
+ <form method="POST" action="{{links.undo-edit-post.url}}"
class="flow-post">
+ <input type="hidden" name="wpEditToken"
value="{{@root.rootBlock.editToken}}" />
+ <input type="hidden" name="topic_prev_revision"
value="{{current.revisionId}}" />
+ <input type="hidden" name="topic_postId"
value="{{current.postId}}" />
+
+ <textarea name="topic_content"
+ class="mw-ui-input"
+ data-role="content"
+ data-flow-preview-template="flow_post"
+ data-flow-preview-title="{{articleTitle}}"
+ data-flow-username="{{current.creator.name}}"
+ >
+ {{~#if submitted.content~}}
+ {{~submitted.content~}}
+ {{~else~}}
+ {{~#if undo.possible~}}
+ {{~undo.content~}}
+ {{~else~}}
+ {{~current.content.content~}}
+ {{~/if~}}
+ {{~/if~}}
+ </textarea>
+
+ <div class="flow-form-actions flow-form-collapsible">
+ <button class="mw-ui-button mw-ui-constructive">
+ {{~l10n "flow-edit-post-submit"~}}
+ </button>
+ {{> flow_form_buttons}}
+ <small class="flow-terms-of-use plainlinks">
+ {{~l10nParse "flow-terms-of-use-edit"}}
+ </small>
+ </div>
+ </form>
+</div>
+
diff --git a/handlebars/flow_block_topicsummary_undo_edit.handlebars
b/handlebars/flow_block_topicsummary_undo_edit.handlebars
new file mode 100644
index 0000000..dabe2b1
--- /dev/null
+++ b/handlebars/flow_block_topicsummary_undo_edit.handlebars
@@ -0,0 +1,47 @@
+<div class="flow-board">
+ {{#if undo.possible}}
+ <p>{{l10n "flow-undo-edit-content"}}</p>
+ {{else}}
+ <p class="error">{{l10n "flow-undo-edit-failure"}}</p>
+ {{/if}}
+
+ {{> flow_errors}}
+
+ {{#if undo.possible}}
+ {{diffUndo undo.diff_content}}
+ {{/if}}
+
+ <form method="POST" action="{{links.undo-edit-header.url}}"
class="flow-post">
+ <input type="hidden" name="wpEditToken"
value="{{@root.rootBlock.editToken}}" />
+ <input type="hidden" name="topicsummary_prev_revision"
value="{{current.revisionId}}" />
+
+ <textarea name="topicsummary_summary"
+ class="mw-ui-input"
+ data-role="content"
+ data-flow-preview-node="summary"
+
data-flow-preview-template="flow_topic_titlebar_summary.partial"
+ data-flow-preview-title="{{articleTitle}}"
+ >
+ {{~#if submitted.content~}}
+ {{~submitted.content~}}
+ {{~else~}}
+ {{~#if undo.possible~}}
+ {{~undo.content~}}
+ {{~else~}}
+ {{~current.content.content~}}
+ {{~/if~}}
+ {{~/if~}}
+ </textarea>
+
+ <div class="flow-form-actions flow-form-collapsible">
+ <button class="mw-ui-button mw-ui-constructive">
+ {{~l10n "flow-topic-action-summarize-topic"~}}
+ </button>
+ {{> flow_form_buttons}}
+ <small class="flow-terms-of-use plainlinks">
+ {{~l10nParse "flow-terms-of-use-summarize"}}
+ </small>
+ </div>
+ </form>
+</div>
+
diff --git a/handlebars/flow_edit_post.partial.handlebars
b/handlebars/flow_edit_post.partial.handlebars
index dc15fdb..3a3aa5b 100644
--- a/handlebars/flow_edit_post.partial.handlebars
+++ b/handlebars/flow_edit_post.partial.handlebars
@@ -12,6 +12,7 @@
<textarea name="topic_content" class="mw-ui-input flow-form-collapsible"
data-flow-preview-template="flow_post"
data-flow-preview-title="{{articleTitle}}"
+ data-flow-creator="{{creator.name}}"
data-role="content">
{{~#if @root.rootBlock.submitted.content~}}
{{[email protected]~}}
diff --git a/handlebars/flow_history_line.partial.handlebars
b/handlebars/flow_history_line.partial.handlebars
index 45371b9..9e85132 100644
--- a/handlebars/flow_history_line.partial.handlebars
+++ b/handlebars/flow_history_line.partial.handlebars
@@ -38,7 +38,6 @@
{{showCharacterDifference size.old size.new}}
{{/if}}
-
<ul class="flow-history-moderation-menu">
{{!-- Inserts each common flow-history-moderation-action --}}
{{> flow_moderation_actions_list this moderationType="history"
moderationTarget="post" moderationTemplate="post"
moderationMwUiClass="mw-ui-anchor" moderationIcons=false}}
diff --git a/handlebars/flow_moderation_actions_list.partial.handlebars
b/handlebars/flow_moderation_actions_list.partial.handlebars
index 8651c29..1a06b22 100644
--- a/handlebars/flow_moderation_actions_list.partial.handlebars
+++ b/handlebars/flow_moderation_actions_list.partial.handlebars
@@ -77,9 +77,24 @@
</li>
{{~/if~}}
{{~/ifCond~}}
+
</section>
<section>
+ {{~#ifCond moderationType "===" "history"~}}
+ {{!-- Board history only --}}
+ {{~#if actions.undo~}}
+ <li>
+ {{~noop~}}
+ <a class="{{moderationMwUiClass}} mw-ui-quiet"
+ href="{{actions.undo.url}}"
+ >
+ {{~actions.undo.title~}}
+ </a>
+ {{~noop~}}
+ </li>
+ {{~/if~}}
+ {{~/ifCond~}}
{{~#if actions.hide~}}
<li>
{{~noop~}}
diff --git a/i18n/en.json b/i18n/en.json
index 372a974..1224580 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -498,6 +498,19 @@
"apihelp-flow-parsoid-utils-example-1": "Convert wikitext
<nowiki>'''lorem''' ''blah''</nowiki> to HTML",
"apihelp-query+flowinfo-description": "Get basic Flow information about
a page.",
"apihelp-query+flowinfo-example-1": "Fetch Flow information about
[[Talk:Sandbox]], [[Main Page]], and [[Talk:Flow]]",
+ "apihelp-flow+undo-edit-header-description": "Retrieve information
necessary to undo header edits.",
+ "apihelp-flow+undo-edit-header-param-startId": "Revision id to start
undo at.",
+ "apihelp-flow+undo-edit-header-param-endId": "Revision id to end undo
at.",
+ "apihelp-flow+undo-edit-header-example-1": "Fetch information about
undoing a header edit at [[Talk:Sandbox]]",
+ "apihelp-flow+undo-edit-post-description": "Retrieve information
necesary to undo post edit.",
+ "apihelp-flow+undo-edit-post-param-postId": "Post id to be undone.",
+ "apihelp-flow+undo-edit-post-param-startId": "Revision id to start undo
at.",
+ "apihelp-flow+undo-edit-post-param-endId": "Revision id to end undo
at.",
+ "apihelp-flow+undo-edit-post-example-1": "Fetch information about
undoing a post edit in a specific topic.",
+ "apihelp-flow+undo-edit-topic-summary-description": "Retrieve
information necessary to undo topic summary edits.",
+ "apihelp-flow+undo-edit-topic-summary-param-startId": "Revision id to
start undo at.",
+ "apihelp-flow+undo-edit-topic-summary-param-endId": "Revision id to end
undo at.",
+ "apihelp-flow+undo-edit-topic-summary-example-1": "Fetch information
about undoing a topic summary edit in a specific topic",
"flow-edited": "Edited",
"flow-edited-by": "Edited by $1",
"flow-lqt-redirect-reason": "Redirecting retired LiquidThreads post to
its converted Flow post",
@@ -505,6 +518,14 @@
"flow-talk-conversion-archive-edit-reason": "Wikitext talk to Flow
conversion",
"flow-previous-diff": "← Older edit",
"flow-next-diff": "Newer edit →",
+ "flow-undo": "undo",
+ "flow-undo-latest-revision": "Latest revision",
+ "flow-undo-your-text": "Your text",
+ "flow-undo-edit-header": "Editing the header",
+ "flow-undo-edit-topic-summary": "Editing the topic summary",
+ "flow-undo-edit-post": "Editing a post",
+ "flow-undo-edit-content": "The edit can be undone. Please check the
comparison below to verify that this is what you want to do, and then save the
changes below to finish undoing the edit.",
+ "flow-undo-edit-failure": "The edit could not be undone due to
conflicting intermediate edits.",
"group-flow-bot": "Flow bots",
"group-flow-bot-member": "Flow bot",
"grouppage-flow-bot": "Project:Flow bots"
diff --git a/i18n/qqq.json b/i18n/qqq.json
index f3d3184..e064573 100644
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -503,6 +503,19 @@
"apihelp-flow-parsoid-utils-example-1":
"{{doc-apihelp-example|flow-parsoid-utils}}",
"apihelp-query+flowinfo-description":
"{{doc-apihelp-description|query+flowinfo}}",
"apihelp-query+flowinfo-example-1":
"{{doc-apihelp-example|query+flowinfo}}",
+ "apihelp-flow+undo-edit-header-description":
"{{doc-apihelp-description|flow+undo-edit-header}}",
+ "apihelp-flow+undo-edit-header-param-startId":
"{{doc-apihelp-param|flow+undo-edit-header|startId}}",
+ "apihelp-flow+undo-edit-header-param-endId":
"{{doc-apihelp-param|flow+undo-edit-header|endId}}",
+ "apihelp-flow+undo-edit-header-example-1":
"{{doc-apihelp-example|flow+undo-edit-header}}",
+ "apihelp-flow+undo-edit-post-description":
"{{doc-apihelp-description|flow+undo-edit-post}}",
+ "apihelp-flow+undo-edit-post-param-postId":
"{{doc-apihelp-param|flow+undo-edit-post|postId}}",
+ "apihelp-flow+undo-edit-post-param-startId":
"{{doc-apihelp-param|flow+undo-edit-post|startId}}",
+ "apihelp-flow+undo-edit-post-param-endId":
"{{doc-apihelp-param|flow+undo-edit-post|endId}}",
+ "apihelp-flow+undo-edit-post-example-1":
"{{doc-apihelp-example|flow+undo-edit-post}}",
+ "apihelp-flow+undo-edit-topic-summary-description":
"{{doc-apihelp-description|flow+undo-edit-topic-summary}}",
+ "apihelp-flow+undo-edit-topic-summary-param-startId":
"{{doc-apihelp-param|flow+undo-edit-topic-summary|startId}}",
+ "apihelp-flow+undo-edit-topic-summary-param-endId":
"{{doc-apihelp-param|flow+undo-edit-topic-summary|endId}}",
+ "apihelp-flow+undo-edit-topic-summary-example-1":
"{doc-apihelp-example|flow+undo-edit-topic-summary}}",
"flow-edited": "Message displayed below a post to indicate it has last
been edited by the original author\n{{Identical|Edited}}",
"flow-edited-by": "Message displayed below a post to indicate it has
last been edited by a user other than the original author",
"flow-lqt-redirect-reason": "Edit summary used to redirect old LQT
thread pages to Flow topics",
@@ -510,6 +523,14 @@
"flow-talk-conversion-archive-edit-reason": "Message used as an edit
summary when appending a template to a wikitext talk page after archiving it in
preparation for conversion to Flow.",
"flow-previous-diff": "Text used on diff pages to link to the previous
diff. For right-to-left languages use →.",
"flow-next-diff": "Text used on diff pages to link to the next diff.
For right-to-left languages use ←.",
+ "flow-undo": "Used as link text to go to the page to undo a revision",
+ "flow-undo-latest-revision": "Text shown above an undo diff for the
left hand side.",
+ "flow-undo-your-text": "Text shown above an undo diff for the right
hand side.",
+ "flow-undo-edit-header": "Page title when undoing a header edit.",
+ "flow-undo-edit-topic-summary": "Page title when undoing a topic
summary edit.",
+ "flow-undo-edit-post": "Page title when undoing a post edit.",
+ "flow-undo-edit-content": "Text shown on undo pages informing the user
that the edit can be undone cleanly.",
+ "flow-undo-edit-failure": "Error message shown on undo pages when the
revision cannot be directly undone.",
"group-flow-bot": "{{doc-group|flow-bot}}",
"group-flow-bot-member": "{{doc-group|flow-bot|member}}",
"grouppage-flow-bot": "{{doc-group|flow-bot|page}}"
diff --git a/includes/Actions/UndoEditHeaderAction.php
b/includes/Actions/UndoEditHeaderAction.php
new file mode 100644
index 0000000..8bfe20b
--- /dev/null
+++ b/includes/Actions/UndoEditHeaderAction.php
@@ -0,0 +1,12 @@
+<?php
+
+namespace Flow\Actions;
+
+use IContextSource;
+use Page;
+
+class UndoEditHeaderAction extends FlowAction {
+ function __construct( Page $page, IContextSource $context ) {
+ parent::__construct( $page, $context, 'undo-edit-header' );
+ }
+}
diff --git a/includes/Actions/UndoEditPostAction.php
b/includes/Actions/UndoEditPostAction.php
new file mode 100644
index 0000000..e4b44cb
--- /dev/null
+++ b/includes/Actions/UndoEditPostAction.php
@@ -0,0 +1,12 @@
+<?php
+
+namespace Flow\Actions;
+
+use IContextSource;
+use Page;
+
+class UndoEditPostAction extends FlowAction {
+ function __construct( Page $page, IContextSource $context ) {
+ parent::__construct( $page, $context, 'undo-edit-post' );
+ }
+}
diff --git a/includes/Actions/UndoEditTopicSummaryAction.php
b/includes/Actions/UndoEditTopicSummaryAction.php
new file mode 100644
index 0000000..e5624c2
--- /dev/null
+++ b/includes/Actions/UndoEditTopicSummaryAction.php
@@ -0,0 +1,12 @@
+<?php
+
+namespace Flow\Actions;
+
+use IContextSource;
+use Page;
+
+class UndoEditTopicSummaryAction extends FlowAction {
+ function __construct( Page $page, IContextSource $context ) {
+ parent::__construct( $page, $context, 'undo-edit-topic-summary'
);
+ }
+}
diff --git a/includes/Block/Header.php b/includes/Block/Header.php
index a4deee8..05292e3 100644
--- a/includes/Block/Header.php
+++ b/includes/Block/Header.php
@@ -36,7 +36,7 @@
/**
* @var string[]
*/
- protected $supportedPostActions = array( 'edit-header' );
+ protected $supportedPostActions = array( 'edit-header',
'undo-edit-header' );
/**
* @var string[]
@@ -46,13 +46,14 @@
/**
* @var string[]
*/
- protected $supportedGetActions = array( 'view',
'compare-header-revisions', 'edit-header', 'view-header' );
+ protected $supportedGetActions = array( 'view',
'compare-header-revisions', 'edit-header', 'view-header', 'undo-edit-header' );
// @Todo - fill in the template names
protected $templates = array(
'view' => '',
'compare-header-revisions' => 'diff_view',
'edit-header' => 'edit',
+ 'undo-edit-header' => 'undo_edit',
'view-header' => 'single_view',
);
@@ -203,6 +204,10 @@
$output += $this->renderRevisionApi();
break;
+ case 'undo-edit-header':
+ $output = $this->renderUndoApi( $options ) +
$output;
+ break;
+
case 'view-header':
if ( isset( $options['revId'] ) &&
$options['revId'] ) {
$output += $this->renderSingleViewApi(
$options['revId'] );
@@ -217,6 +222,7 @@
case 'compare-header-revisions':
$output += $this->renderDiffviewApi( $options );
break;
+
}
if ( $this->wasSubmitted() ) {
@@ -297,6 +303,26 @@
return $output;
}
+ protected function renderUndoApi( array $options ) {
+ if ( $this->workflow->isNew() ) {
+ throw new FlowException( 'No header exists to undo' );
+ }
+
+ if ( !isset( $options['startId'], $options['endId'] ) ) {
+ throw new InvalidInputException( 'Both startId and
endId must be provided' );
+ }
+
+ /** @var RevisionViewQuery */
+ $query = Container::get( 'query.header.view' );
+ $rows = $query->getUndoDiffResult( $options['startId'],
$options['endId'] );
+ if ( !$rows ) {
+ throw new InvalidInputException( 'Could not load
revision to undo' );
+ }
+
+ $serializer = Container::get( 'formatter.undoedit' );
+ return $serializer->formatApi( $rows[0], $rows[1], $rows[2],
$this->context );
+ }
+
public function getName() {
return 'header';
}
diff --git a/includes/Block/Topic.php b/includes/Block/Topic.php
index b97b84c..719b274 100644
--- a/includes/Block/Topic.php
+++ b/includes/Block/Topic.php
@@ -11,8 +11,9 @@
use Flow\Exception\InvalidDataException;
use Flow\Exception\InvalidInputException;
use Flow\Exception\PermissionException;
-use Flow\Formatter\TopicHistoryQuery;
use Flow\Formatter\PostHistoryQuery;
+use Flow\Formatter\RevisionViewQuery;
+use Flow\Formatter\TopicHistoryQuery;
use Flow\Model\AbstractRevision;
use Flow\Model\PostRevision;
use Flow\Model\UUID;
@@ -63,6 +64,7 @@
'lock-topic',
// Other stuff
'edit-title',
+ 'undo-edit-post',
// psuedo-action, we don't do anything but we return
// information about the topic in the api response
'edit-topic-summary',
@@ -70,7 +72,7 @@
protected $supportedGetActions = array(
'reply', 'view', 'history', 'edit-post', 'edit-title',
'compare-post-revisions', 'single-view',
- 'view-topic', 'view-post',
+ 'view-topic', 'view-post', 'undo-edit-post',
'moderate-topic', 'moderate-post', 'lock-topic',
);
@@ -81,6 +83,7 @@
'reply' => '',
'history' => 'history',
'edit-post' => '',
+ 'undo-edit-post' => 'undo_edit',
'edit-title' => 'edit_title',
'compare-post-revisions' => 'diff_view',
'moderate-topic' => 'moderate_topic',
@@ -145,6 +148,7 @@
$this->validateModeratePost();
break;
+ case 'undo-edit-post':
case 'edit-post':
$this->validateEditPost();
break;
@@ -420,6 +424,7 @@
case 'restore-post':
case 'moderate-post':
case 'edit-title':
+ case 'undo-edit-post':
case 'edit-post':
if ( $this->newRevision === null ) {
throw new FailCommitException( 'Attempt to save
null revision', 'fail-commit' );
@@ -502,6 +507,8 @@
$output += $result['revisions'][$revisionId];
} elseif ( $this->action === 'compare-post-revisions' ) {
$output += $this->renderDiffViewApi( $options );
+ } elseif ( $this->action === 'undo-edit-post' ) {
+ $output += $this->renderUndoApi( $options );
} elseif ( $this->shouldRenderTopicApi( $options ) ) {
// view full topic
$output += $this->renderTopicApi( $options );
@@ -650,6 +657,26 @@
$serialized['revisionId'] => $serialized,
)
);
+ }
+
+ protected function renderUndoApi( array $options ) {
+ if ( $this->workflow->isNew() ) {
+ throw new FlowException( 'No posts can exist for
non-existent topic' );
+ }
+
+ if ( !isset( $options['startId'], $options['endId'] ) ) {
+ throw new InvalidInputException( 'Both startId and
endId must be provided' );
+ }
+
+ /** @var RevisionViewQuery */
+ $query = Container::get( 'query.post.view' );
+ $rows = $query->getUndoDiffResult( $options['startId'],
$options['endId'] );
+ if ( !$rows ) {
+ throw new InvalidInputException( 'Could not load
revision to undo' );
+ }
+
+ $serializer = Container::get( 'formatter.undoedit' );
+ return $serializer->formatApi( $rows[0], $rows[1], $rows[2],
$this->context );
}
protected function getRevisionFormatter() {
@@ -926,7 +953,12 @@
$title = $this->workflow->getOwnerTitle();
$out->setPageTitle( $out->msg( 'flow-topic-first-heading',
$title->getPrefixedText() ) );
if ( $this->permissions->isAllowed( $topic, 'view' ) ) {
- $out->setHtmlTitle( $out->msg( 'flow-topic-html-title',
array(
+ if ( $this->action === 'undo-edit-post' ) {
+ $key = 'flow-undo-edit-post';
+ } else {
+ $key = 'flow-topic-html-title';
+ }
+ $out->setHtmlTitle( $out->msg( $key, array(
// This must be a rawParam to not expand
{{foo}} in the title, it must
// not be htmlspecialchar'd because
OutputPage::setHtmlTitle handles that.
Message::rawParam( $topic->getContent(
'wikitext' ) ),
diff --git a/includes/Block/TopicSummary.php b/includes/Block/TopicSummary.php
index 407c1aa..1f47a0a 100644
--- a/includes/Block/TopicSummary.php
+++ b/includes/Block/TopicSummary.php
@@ -41,22 +41,23 @@
/**
* @var string[]
*/
- protected $supportedPostActions = array( 'edit-topic-summary' );
+ protected $supportedPostActions = array( 'edit-topic-summary',
'undo-edit-topic-summary' );
/**
* @var string[]
*/
- protected $supportedGetActions = array( 'view-topic-summary',
'compare-postsummary-revisions', 'edit-topic-summary' );
+ protected $supportedGetActions = array( 'view-topic-summary',
'compare-postsummary-revisions', 'edit-topic-summary',
'undo-edit-topic-summary' );
/**
* @var string[]
*/
- protected $requiresWikitext = array( 'edit-topic-summary' );
+ protected $requiresWikitext = array( 'edit-topic-summary',
'undo-edit-topic-summary' );
protected $templates = array(
'view-topic-summary' => 'single_view',
'compare-postsummary-revisions' => 'diff_view',
'edit-topic-summary' => 'edit',
+ 'undo-edit-topic-summary' => 'undo_edit',
);
/**
@@ -81,6 +82,7 @@
*/
public function validate() {
switch( $this->action ) {
+ case 'undo-edit-topic-summary':
case 'edit-topic-summary':
$this->validateTopicSummary();
break;
@@ -218,6 +220,7 @@
*/
public function commit() {
switch( $this->action ) {
+ case 'undo-edit-topic-summary':
case 'edit-topic-summary':
return $this->saveTopicSummary();
break;
@@ -268,6 +271,9 @@
break;
case 'edit-topic-summary':
$output += $this->renderNewestTopicSummary();
+ break;
+ case 'undo-edit-topic-summary':
+ $output = $this->renderUndoApi( $options ) +
$output;
break;
case 'compare-postsummary-revisions':
// @Todo - duplicated logic in other diff view
block
@@ -320,6 +326,26 @@
return $output;
}
+ protected function renderUndoApi( array $options ) {
+ if ( $this->workflow->isNew() ) {
+ throw new FlowException( 'No header exists to undo' );
+ }
+
+ if ( !isset( $options['startId'], $options['endId'] ) ) {
+ throw new InvalidInputException( 'Both startId and
endId must be provided' );
+ }
+
+ /** @var RevisionViewQuery */
+ $query = Container::get( 'query.postsummary.view' );
+ $rows = $query->getUndoDiffResult( $options['startId'],
$options['endId'] );
+ if ( !$rows ) {
+ throw new InvalidInputException( 'Could not load
revision to undo' );
+ }
+
+ $serializer = Container::get( 'formatter.undoedit' );
+ return $serializer->formatApi( $rows[0], $rows[1], $rows[2],
$this->context );
+ }
+
public function getName() {
return 'topicsummary';
}
@@ -332,7 +358,12 @@
$title = $this->workflow->getOwnerTitle();
$out->setPageTitle( $out->msg( 'flow-topic-first-heading',
$title->getPrefixedText() ) );
if ( $this->permissions->isAllowed( $topic, 'view' ) ) {
- $out->setHtmlTitle( $out->msg( 'flow-topic-html-title',
array(
+ if ( $this->action === 'undo-edit-topic-summary' ) {
+ $key = 'flow-undo-edit-topic-summary';
+ } else {
+ $key = 'flow-topic-html-title';
+ }
+ $out->setHtmlTitle( $out->msg( $key, array(
// This must be a rawParam to not expand
{{foo}} in the title, it must
// not be htmlspecialchar'd because
OutputPage::setHtmlTitle handles that.
Message::rawParam( $topic->getContent(
'wikitext' ) ),
diff --git a/includes/Formatter/RevisionFormatter.php
b/includes/Formatter/RevisionFormatter.php
index b99cd0d..e64d083 100644
--- a/includes/Formatter/RevisionFormatter.php
+++ b/includes/Formatter/RevisionFormatter.php
@@ -518,6 +518,15 @@
->editPostAction( $title, $workflowId,
$postId, $revId );
break;
+ case 'undo-edit-header':
+ case 'undo-edit-post':
+ case 'undo-edit-topic-summary':
+ if ( !$revision->isFirstRevision() ) {
+ $links['undo'] =
$this->urlGenerator->undoAction( $revision, $title, $workflowId );
+ }
+ break;
+
+
case 'hide-post':
if ( !$postId ) {
throw new FlowException( "$type called
without \$postId" );
diff --git a/includes/Formatter/RevisionUndoViewFormatter.php
b/includes/Formatter/RevisionUndoViewFormatter.php
new file mode 100644
index 0000000..f9db447
--- /dev/null
+++ b/includes/Formatter/RevisionUndoViewFormatter.php
@@ -0,0 +1,71 @@
+<?php
+
+namespace Flow\Formatter;
+
+use DifferenceEngine;
+use Flow\Model\AbstractRevision;
+use IContextSource;
+use TextContent;
+
+class RevisionUndoViewFormatter {
+ protected $revisionViewFormatter;
+
+ public function __construct( RevisionViewFormatter
$revisionViewFormatter ) {
+ $this->revisionViewFormatter = $revisionViewFormatter;
+ }
+
+ /**
+ * Undoes the change that occured between $start and $stop
+ */
+ public function formatApi(
+ FormatterRow $start,
+ FormatterRow $stop,
+ FormatterRow $current,
+ IContextSource $context
+ ) {
+ $undoContent = $this->getUndoContent(
+ $start->revision->getContent( 'wikitext' ),
+ $stop->revision->getContent( 'wikitext' ),
+ $current->revision->getContent( 'wikitext' )
+ );
+
+ $differenceEngine = new DifferenceEngine();
+ $differenceEngine->setContent(
+ new TextContent( $current->revision->getContent(
'wikitext' ) ),
+ new TextContent( $undoContent )
+ );
+
+ $this->revisionViewFormatter->setContentFormat( 'wikitext' );
+
+ // @todo if stop === current we could do a little less
processing
+ return array(
+ 'start' => $this->revisionViewFormatter->formatApi(
$start, $context ),
+ 'stop' => $this->revisionViewFormatter->formatApi(
$stop, $context ),
+ 'current' => $this->revisionViewFormatter->formatApi(
$current, $context ),
+ 'undo' => array(
+ 'possible' => $undoContent !== false,
+ 'content' => $undoContent,
+ 'diff_content' =>
$differenceEngine->getDiffBody(),
+ ),
+ 'articleTitle' => $start->workflow->getArticleTitle(),
+ // overrides the default modules list to only pull in
ext.flow.undo
+ 'modules' => array( 'ext.flow.undo' ),
+ 'moduleStyles' => array( 'ext.flow.undo.styles' ),
+ );
+ }
+
+ protected function getUndoContent( $startContent, $stopContent,
$currentContent ) {
+
+ if ( $currentContent === $stopContent ) {
+ return $startContent;
+ } else {
+ // 3-way merge
+ $ok = wfMerge( $stopContent, $startContent,
$currentContent, $result );
+ if ( $ok ) {
+ return $result;
+ } else {
+ return false;
+ }
+ }
+ }
+}
diff --git a/includes/Formatter/RevisionViewFormatter.php
b/includes/Formatter/RevisionViewFormatter.php
index 69e9cc8..b17a23d 100644
--- a/includes/Formatter/RevisionViewFormatter.php
+++ b/includes/Formatter/RevisionViewFormatter.php
@@ -28,6 +28,10 @@
$this->serializer = $serializer;
}
+ public function setContentFormat( $format, UUID $revisionId = null ) {
+ $this->serializer->setContentFormat( $format, $revisionId );
+ }
+
/**
* @param FormatterRow $row
* @param IContextSource $ctx
diff --git a/includes/Formatter/RevisionViewQuery.php
b/includes/Formatter/RevisionViewQuery.php
index 05e97a0..bdca33b 100644
--- a/includes/Formatter/RevisionViewQuery.php
+++ b/includes/Formatter/RevisionViewQuery.php
@@ -2,14 +2,34 @@
namespace Flow\Formatter;
-use Flow\Container;
+use Flow\Data\ManagerGroup;
use Flow\Exception\InvalidInputException;
use Flow\Exception\PermissionException;
use Flow\Model\AbstractRevision;
use Flow\Model\UUID;
+use Flow\Repository\TreeRepository;
use Flow\RevisionActionPermissions;
abstract class RevisionViewQuery extends AbstractQuery {
+
+ /**
+ * @var RevisionActionPermissions
+ */
+ protected $permissions;
+
+ /**
+ * @param ManagerGroup $storage
+ * @param TreeRepository $treeRepository
+ * @param RevisionActionPermissions $permissions
+ */
+ public function __construct(
+ ManagerGroup $storage,
+ TreeRepository $treeRepository,
+ RevisionActionPermissions $permissions
+ ) {
+ parent::__construct( $storage, $treeRepository );
+ $this->permissions = $permissions;
+ }
/**
* Create a revision based on revisionId
@@ -73,9 +93,10 @@
}
/** @var RevisionActionPermissions $permission */
- $permission = Container::get( 'permissions' );
- // Todo - Check the permission before invoking this function?
- if ( !$permission->isAllowed( $oldRev, 'view' ) ||
!$permission->isAllowed( $newRev, 'view' ) ) {
+ if (
+ !$this->permission->isAllowed( $oldRev, 'view' ) ||
+ !$this->permission->isAllowed( $newRev, 'view' )
+ ) {
throw new PermissionException( 'Insufficient permission
to compare revisions', 'insufficient-permission' );
}
@@ -87,6 +108,40 @@
);
}
+ public function getUndoDiffResult( $startUndoId, $endUndoId ) {
+ $start = $this->createRevision( $startUndoId );
+ if ( !$start ) {
+ throw new InvalidInputException( 'Could not find
revision: ' . $startUndoId, 'missing-revision' );
+ }
+ $end = $this->createRevision( $endUndoId );
+ if ( !$end ) {
+ throw new InvalidInputException( 'Could not find
revision: ' . $endUndoId, 'missing-revision' );
+ }
+
+ // the two revision must have the same revision type id
+ if ( !$start->getCollectionId()->equals(
$end->getCollectionId() ) ) {
+ throw new InvalidInputException( 'start and end are not
from the same set' );
+ }
+
+ $current = $start->getCollection()->getLastRevision();
+
+ if (
+ !$this->permissions->isAllowed( $start, 'view' ) ||
+ !$this->permissions->isAllowed( $end, 'view' ) ||
+ !$this->permissions->isAllowed( $current, 'view' )
+ ) {
+ throw new PermissionException( 'Insufficient permission
to undo revisions', 'insufficient-permission' );
+ }
+
+ $this->loadMetadataBatch( array( $start, $end, $current ) );
+
+ return array(
+ $this->buildResult( $start, null ),
+ $this->buildResult( $end, null ),
+ $this->buildResult( $current, null ),
+ );
+ }
+
public function isComparable( AbstractRevision $cur, AbstractRevision
$prev ) {
if ( $cur->getRevisionType() == $prev->getRevisionType() ) {
return $cur->getCollectionId()->equals(
$prev->getCollectionId() );
diff --git a/includes/TemplateHelper.php b/includes/TemplateHelper.php
index 3d48b70..d471d3b 100644
--- a/includes/TemplateHelper.php
+++ b/includes/TemplateHelper.php
@@ -163,6 +163,7 @@
'showCharacterDifference' =>
'Flow\TemplateHelper::showCharacterDifference',
'l10nParse' =>
'Flow\TemplateHelper::l10nParse',
'diffRevision' =>
'Flow\TemplateHelper::diffRevision',
+ 'diffUndo' =>
'Flow\TemplateHelper::diffUndo',
'moderationAction' =>
'Flow\TemplateHelper::moderationAction',
'concat' =>
'Flow\TemplateHelper::concat',
'user' => 'Flow\TemplateHelper::user',
@@ -562,6 +563,31 @@
) );
}
+ static public function diffUndo( array $args, array $named ) {
+ if ( count( $args ) !== 1 ) {
+ throw new WrongNumberArgumentsException( $args, 'one' );
+ }
+ list( $diffContent ) = $args;
+
+ $differenceEngine = new \DifferenceEngine();
+ $multi = $differenceEngine->getMultiNotice();
+ $notice = '';
+ if ( $diffContent === '' ) {
+ $notice = '<div class="mw-diff-empty">' .
+ wfMessage( 'diff-empty' )->parse() .
+ "</div>\n";
+ }
+ $differenceEngine->showDiffStyle();
+
+ return self::html( $differenceEngine->addHeader(
+ $diffContent,
+ wfMessage( 'flow-undo-latest-revision' ),
+ wfMessage( 'flow-undo-your-text' ),
+ $multi,
+ $notice
+ ) );
+ }
+
/**
* @param array $args Expects array $actions, string $moderationState
* @param array $named No named arguments expected
diff --git a/includes/UrlGenerator.php b/includes/UrlGenerator.php
index 7e1de26..4bcb8d2 100644
--- a/includes/UrlGenerator.php
+++ b/includes/UrlGenerator.php
@@ -265,6 +265,87 @@
}
/**
+ * Generate a link to undo the specified revision. Note that this will
only work if
+ * that is the most recent content edit against the revision type.
+ *
+ * @param AbstractRevision $revision The revision to undo.
+ * @param Title|null $title The title the revision belongs to
+ * @param UUID $workflowId The workflow id the revision belongs to
+ * @return Anchor
+ * @throws FlowException When the provided revision is not known
+ */
+ public function undoAction( AbstractRevision $revision, Title $title =
null, UUID $workflowId ) {
+ $startId = $revision->getPrevRevisionId();
+ $endId = $revision->getRevisionId();
+ if ( $revision instanceof PostRevision ) {
+ return $this->undoEditPostAction( $title, $workflowId,
$startId, $endId );
+ } elseif ( $revision instanceof Header ) {
+ return $this->undoEditHeaderAction( $title,
$workflowId, $startId, $endId );
+ } elseif ( $revision instanceof PostSummary ) {
+ return $this->undoEditSummaryAction( $title,
$workflowId, $startId, $endId );
+ } else {
+ throw new FlowException( 'Unknown revision type: ' .
get_class( $revision ) );
+ }
+ }
+
+ /**
+ * @param Title|null $title The title the post belongs to, or null
+ * @param UUID $workflowId The workflowId the post belongs to
+ * @param UUID $startId The revision to start undo from.
+ * @param UUID $endId The revision to stop undoing at
+ * @return Anchor
+ */
+ public function undoEditPostAction( Title $title = null, UUID
$workflowId, UUID $startId, UUID $endId ) {
+ return new Anchor(
+ wfMessage( 'flow-undo' ),
+ $this->resolveTitle( $title, $workflowId ),
+ array(
+ 'action' => 'undo-edit-post',
+ 'topic_startId' => $startId->getAlphadecimal(),
+ 'topic_endId' => $endId->getAlphadecimal(),
+ )
+ );
+ }
+
+ /**
+ * @param Title|null $title The title the header belongs to, or null
+ * @param UUID $workflowId The workflowId the header belongs to
+ * @param UUID $startId The revision to start undo from.
+ * @param UUID $endId The revision to stop undoing at
+ * @return Anchor
+ */
+ public function undoEditHeaderAction( Title $title = null, UUID
$workflowId, UUID $startId, UUID $endId ) {
+ return new Anchor(
+ wfMessage( 'flow-undo' ),
+ $this->resolveTitle( $title, $workflowId ),
+ array(
+ 'action' => 'undo-edit-header',
+ 'header_startId' => $startId->getAlphadecimal(),
+ 'header_endId' => $endId->getAlphadecimal(),
+ )
+ );
+ }
+
+ /**
+ * @param Title|null $title The title the summary belongs to, or null
+ * @param UUID $workflowId The workflowId the summary belongs to
+ * @param UUID $startId The revision to start undo from.
+ * @param UUID $endId The revision to stop undoing at
+ * @return Anchor
+ */
+ public function undoEditSummaryAction( Title $title = null, UUID
$workflowId, UUID $startId, UUID $endId ) {
+ return new Anchor(
+ wfMessage( 'flow-undo' ),
+ $this->resolveTitle( $title, $workflowId ),
+ array(
+ 'action' => 'undo-edit-topic-summary',
+ 'topicsummary_startId' =>
$startId->getAlphadecimal(),
+ 'topicsummary_endId' =>
$endId->getAlphadecimal(),
+ )
+ );
+ }
+
+ /**
* @param AbstractRevision $revision
* @param Title|null $title
* @param UUID $workflowId
diff --git a/includes/View.php b/includes/View.php
index 0e9a3cf..9e52995 100644
--- a/includes/View.php
+++ b/includes/View.php
@@ -104,6 +104,7 @@
'mediawiki.ui.button',
'mediawiki.ui.input',
'mediawiki.ui.text',
+ 'ext.flow.styles.base' ,
'ext.flow.styles' ,
'ext.flow.mediawiki.ui.tooltips',
'ext.flow.mediawiki.ui.form',
diff --git a/includes/api/ApiFlowUndoEditHeader.php
b/includes/api/ApiFlowUndoEditHeader.php
new file mode 100644
index 0000000..dbb5ae0
--- /dev/null
+++ b/includes/api/ApiFlowUndoEditHeader.php
@@ -0,0 +1,41 @@
+<?php
+
+class ApiFlowUndoEditHeader extends ApiFlowBasePost {
+
+ public function __construct( $api, $modName ) {
+ parent::__construct( $api, $modName, 'ueh' );
+ }
+
+ /**
+ * Taken from ext.flow.base.js
+ * @return array
+ */
+ protected function getBlockParams() {
+ return array( 'header' => $this->extractRequestParams() );
+ }
+
+ protected function getAction() {
+ return 'undo-edit-header';
+ }
+
+ public function getAllowedParams() {
+ return array(
+ 'startId' => array(
+ ApiBase::PARAM_REQUIRED => true,
+ ),
+ 'endId' => array(
+ ApiBase::PARAM_REQUIRED => true,
+ ),
+ ) + parent::getAllowedParams();
+ }
+
+ /**
+ * @see ApiBase::getExamplesMessages()
+ */
+ protected function getExamplesMessages() {
+ return array(
+
'action=flow&submodule=undo-edit-header&page=Talk:Sandbox&uehstartId=???&uehendId=???'
+ => 'apihelp-flow+undo-edit-header-example-1',
+ );
+ }
+}
diff --git a/includes/api/ApiFlowUndoEditPost.php
b/includes/api/ApiFlowUndoEditPost.php
new file mode 100644
index 0000000..33141d6
--- /dev/null
+++ b/includes/api/ApiFlowUndoEditPost.php
@@ -0,0 +1,40 @@
+<?php
+
+class ApiFlowUndoEditPost extends ApiFlowBasePost {
+
+ public function __construct( $api ) {
+ parent::__construct( $api, 'undo-edit-post', 'uep' );
+ }
+
+ protected function getAction() {
+ return 'undo-edit-post';
+ }
+
+ protected function getBlockParams() {
+ return array( 'topic' => $this->extractRequestParams() );
+ }
+
+ public function getAllowedParams() {
+ return array(
+ 'postId' => array(
+ ApiBase::PARAM_REQUIRED => true,
+ ),
+ 'startId' => array(
+ ApiBase::PARAM_REQUIRED => true,
+ ),
+ 'endId' => array(
+ ApiBase::PARAM_REQUIRED => true,
+ ),
+ ) + parent::getAllowedParams();
+ }
+
+ /**
+ * @see ApiBase::getExamplesMessages()
+ */
+ protected function getExamplesMessages() {
+ return array(
+
'action=flow&submodule=undo-edit-post&page=Topic:S2tycnas4hcucw8w&uaepostId=???&uaestartId=???&uaeendId=???'
+ => 'apihelp-flow+undo-edit-post-example-1',
+ );
+ }
+}
diff --git a/includes/api/ApiFlowUndoEditTopicSummary.php
b/includes/api/ApiFlowUndoEditTopicSummary.php
new file mode 100644
index 0000000..996e15a
--- /dev/null
+++ b/includes/api/ApiFlowUndoEditTopicSummary.php
@@ -0,0 +1,40 @@
+<?php
+
+class ApiFlowUndoEditTopicSummary extends ApiFlowBasePost {
+
+ public function __construct( $api ) {
+ parent::__construct( $api, 'edit-topic-summary', 'uets' );
+ }
+
+ protected function getAction() {
+ return 'undo-edit-topic-summary';
+ }
+
+ protected function getBlockParams() {
+ return array(
+ 'topicsummary' => $this->extractRequestParams(),
+ 'topic' => array(),
+ );
+ }
+
+ public function getAllowedParams() {
+ return array(
+ 'startId' => array(
+ ApiBase::PARAM_REQUIRED => true,
+ ),
+ 'endId' => array(
+ ApiBase::PARAM_REQUIRED => true,
+ ),
+ ) + parent::getAllowedParams();
+ }
+
+ /**
+ * @see ApiBase::getExamplesMessages()
+ */
+ protected function getExamplesMessages() {
+ return array(
+
'action=flow&submodule=undo-edit-topic-summary&page=Topic:S2tycnas4hcucw8w&uetsstartId=???&uetsendId=???'
+ =>
'apihelp-flow+undo-edit-topic-summary-example-1',
+ );
+ }
+}
diff --git a/modules/engine/components/board/features/flow-board-preview.js
b/modules/engine/components/board/features/flow-board-preview.js
index 218311f..c706acf 100644
--- a/modules/engine/components/board/features/flow-board-preview.js
+++ b/modules/engine/components/board/features/flow-board-preview.js
@@ -125,7 +125,7 @@
flowBoard = mw.flow.getPrototypeMethod( 'board',
'getInstanceByElement' )( $form ),
$titleField = $form.find( 'input' ).filter(
'[data-role=title]' ),
$target = info.$target,
- username = mw.user.getName(),
+ username = $target.data( 'flow-creator' ) ||
mw.user.getName(),
id = Math.random(),
previewTemplate = $target.data( 'flow-preview-template'
),
contentNode = $target.data( 'flow-preview-node' ) ||
'content';
--
To view, visit https://gerrit.wikimedia.org/r/194047
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I6b45a2c5cdaf40f15a8b02ae5ba707529218538e
Gerrit-PatchSet: 18
Gerrit-Project: mediawiki/extensions/Flow
Gerrit-Branch: master
Gerrit-Owner: EBernhardson <[email protected]>
Gerrit-Reviewer: EBernhardson <[email protected]>
Gerrit-Reviewer: Legoktm <[email protected]>
Gerrit-Reviewer: Matthias Mullie <[email protected]>
Gerrit-Reviewer: SG <[email protected]>
Gerrit-Reviewer: Siebrand <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits