mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-26 00:32:42 +01:00
Add comment linking to Maniphest and Differential
Summary: Allows you to link to comments with "D123#3" or "T123#3", then adds a pile of JS to try to make it not terrible. :/ The thing I'm trying to avoid here is when someone says "look at this! http://blog.com/#comment-239291" and you click and your browser jumps somewhere random and you have no idea which comment they meant. Since I really hate this, I've tried to avoid it by making sure the comment is always highlighted. Test Plan: Put T1#1 and D1#1 in remarkup and verified they linked properly. Clicked anchors on individual comments. Faked all comments hidden in Differential and verified they expanded on anchor or anchor change. Reviewed By: aran Reviewers: aran, tomo, mroch, jungejason, tuomaspelkonen CC: aran, epriestley Differential Revision: 383
This commit is contained in:
parent
ead9bbfeb1
commit
d96d515cc2
22 changed files with 343 additions and 116 deletions
2
externals/javelin
vendored
2
externals/javelin
vendored
|
@ -1 +1 @@
|
|||
Subproject commit 7ac64cd03d89d6d5f8c7f85b32c9611d3866ea2b
|
||||
Subproject commit c714cff45db83fc8c34e82b7ec1155b7c442dc7b
|
|
@ -172,7 +172,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'differential-revision-comment-css' =>
|
||||
array(
|
||||
'uri' => '/res/e3ea8c34/rsrc/css/application/differential/revision-comment.css',
|
||||
'uri' => '/res/e3539439/rsrc/css/application/differential/revision-comment.css',
|
||||
'type' => 'css',
|
||||
'requires' =>
|
||||
array(
|
||||
|
@ -188,6 +188,16 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'disk' => '/rsrc/css/application/differential/revision-comment-list.css',
|
||||
),
|
||||
0 =>
|
||||
array(
|
||||
'uri' => '/res/39de799e/rsrc/js/javelin/docs/Base.js',
|
||||
'type' => 'js',
|
||||
'requires' =>
|
||||
array(
|
||||
0 => 'javelin-install',
|
||||
),
|
||||
'disk' => '/rsrc/js/javelin/docs/Base.js',
|
||||
),
|
||||
'differential-revision-detail-css' =>
|
||||
array(
|
||||
'uri' => '/res/ea9de420/rsrc/css/application/differential/revision-detail.css',
|
||||
|
@ -279,16 +289,6 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'disk' => '/rsrc/js/javelin/lib/behavior.js',
|
||||
),
|
||||
0 =>
|
||||
array(
|
||||
'uri' => '/res/39de799e/rsrc/js/javelin/docs/Base.js',
|
||||
'type' => 'js',
|
||||
'requires' =>
|
||||
array(
|
||||
0 => 'javelin-install',
|
||||
),
|
||||
'disk' => '/rsrc/js/javelin/docs/Base.js',
|
||||
),
|
||||
'javelin-behavior-aphront-basic-tokenizer' =>
|
||||
array(
|
||||
'uri' => '/res/bce3961b/rsrc/js/application/core/behavior-tokenizer.js',
|
||||
|
@ -424,7 +424,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'javelin-behavior-differential-show-all-comments' =>
|
||||
array(
|
||||
'uri' => '/res/b7c7e1ee/rsrc/js/application/differential/behavior-show-all-comments.js',
|
||||
'uri' => '/res/bcc990f0/rsrc/js/application/differential/behavior-show-all-comments.js',
|
||||
'type' => 'js',
|
||||
'requires' =>
|
||||
array(
|
||||
|
@ -560,6 +560,19 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'disk' => '/rsrc/js/application/core/behavior-object-selector.js',
|
||||
),
|
||||
'javelin-behavior-phabricator-watch-anchor' =>
|
||||
array(
|
||||
'uri' => '/res/bb6fa5b2/rsrc/js/application/core/behavior-watch-anchor.js',
|
||||
'type' => 'js',
|
||||
'requires' =>
|
||||
array(
|
||||
0 => 'javelin-behavior',
|
||||
1 => 'javelin-stratcom',
|
||||
2 => 'javelin-util',
|
||||
3 => 'javelin-dom',
|
||||
),
|
||||
'disk' => '/rsrc/js/application/core/behavior-watch-anchor.js',
|
||||
),
|
||||
'javelin-behavior-workflow' =>
|
||||
array(
|
||||
'uri' => '/res/079f49c3/rsrc/js/application/core/behavior-workflow.js',
|
||||
|
@ -574,7 +587,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'javelin-dom' =>
|
||||
array(
|
||||
'uri' => '/res/770d72cd/rsrc/js/javelin/lib/DOM.js',
|
||||
'uri' => '/res/43e9e2de/rsrc/js/javelin/lib/DOM.js',
|
||||
'type' => 'js',
|
||||
'requires' =>
|
||||
array(
|
||||
|
@ -620,7 +633,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'javelin-magical-init' =>
|
||||
array(
|
||||
'uri' => '/res/ce002e50/rsrc/js/javelin/core/init.js',
|
||||
'uri' => '/res/92e7f37e/rsrc/js/javelin/core/init.js',
|
||||
'type' => 'js',
|
||||
'requires' =>
|
||||
array(
|
||||
|
@ -641,7 +654,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'javelin-request' =>
|
||||
array(
|
||||
'uri' => '/res/72a23e59/rsrc/js/javelin/lib/Request.js',
|
||||
'uri' => '/res/1ed0d596/rsrc/js/javelin/lib/Request.js',
|
||||
'type' => 'js',
|
||||
'requires' =>
|
||||
array(
|
||||
|
@ -811,7 +824,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'maniphest-transaction-detail-css' =>
|
||||
array(
|
||||
'uri' => '/res/14758b00/rsrc/css/application/maniphest/transaction-detail.css',
|
||||
'uri' => '/res/7ee02b5e/rsrc/css/application/maniphest/transaction-detail.css',
|
||||
'type' => 'css',
|
||||
'requires' =>
|
||||
array(
|
||||
|
@ -1002,23 +1015,6 @@ celerity_register_resource_map(array(
|
|||
'uri' => '/res/pkg/122a6b6d/workflow.pkg.js',
|
||||
'type' => 'js',
|
||||
),
|
||||
'1ac25e8a' =>
|
||||
array (
|
||||
'name' => 'differential.pkg.css',
|
||||
'symbols' =>
|
||||
array (
|
||||
0 => 'differential-core-view-css',
|
||||
1 => 'differential-changeset-view-css',
|
||||
2 => 'differential-revision-detail-css',
|
||||
3 => 'differential-revision-history-css',
|
||||
4 => 'differential-table-of-contents-css',
|
||||
5 => 'differential-revision-comment-css',
|
||||
6 => 'differential-revision-add-comment-css',
|
||||
7 => 'differential-revision-comment-list-css',
|
||||
),
|
||||
'uri' => '/res/pkg/1ac25e8a/differential.pkg.css',
|
||||
'type' => 'css',
|
||||
),
|
||||
'33f413ef' =>
|
||||
array (
|
||||
'name' => 'typeahead.pkg.js',
|
||||
|
@ -1035,6 +1031,23 @@ celerity_register_resource_map(array(
|
|||
'uri' => '/res/pkg/33f413ef/typeahead.pkg.js',
|
||||
'type' => 'js',
|
||||
),
|
||||
'613cf273' =>
|
||||
array (
|
||||
'name' => 'differential.pkg.css',
|
||||
'symbols' =>
|
||||
array (
|
||||
0 => 'differential-core-view-css',
|
||||
1 => 'differential-changeset-view-css',
|
||||
2 => 'differential-revision-detail-css',
|
||||
3 => 'differential-revision-history-css',
|
||||
4 => 'differential-table-of-contents-css',
|
||||
5 => 'differential-revision-comment-css',
|
||||
6 => 'differential-revision-add-comment-css',
|
||||
7 => 'differential-revision-comment-list-css',
|
||||
),
|
||||
'uri' => '/res/pkg/613cf273/differential.pkg.css',
|
||||
'type' => 'css',
|
||||
),
|
||||
'a6102fe7' =>
|
||||
array (
|
||||
'name' => 'core.pkg.css',
|
||||
|
@ -1059,7 +1072,7 @@ celerity_register_resource_map(array(
|
|||
'uri' => '/res/pkg/a6102fe7/core.pkg.css',
|
||||
'type' => 'css',
|
||||
),
|
||||
'd985d27a' =>
|
||||
'db95a6d0' =>
|
||||
array (
|
||||
'name' => 'javelin.pkg.js',
|
||||
'symbols' =>
|
||||
|
@ -1075,7 +1088,7 @@ celerity_register_resource_map(array(
|
|||
8 => 'javelin-json',
|
||||
9 => 'javelin-uri',
|
||||
),
|
||||
'uri' => '/res/pkg/d985d27a/javelin.pkg.js',
|
||||
'uri' => '/res/pkg/db95a6d0/javelin.pkg.js',
|
||||
'type' => 'js',
|
||||
),
|
||||
'ed383f69' =>
|
||||
|
@ -1104,16 +1117,16 @@ celerity_register_resource_map(array(
|
|||
'aphront-table-view-css' => 'a6102fe7',
|
||||
'aphront-tokenizer-control-css' => 'a6102fe7',
|
||||
'aphront-typeahead-control-css' => 'a6102fe7',
|
||||
'differential-changeset-view-css' => '1ac25e8a',
|
||||
'differential-core-view-css' => '1ac25e8a',
|
||||
'differential-revision-add-comment-css' => '1ac25e8a',
|
||||
'differential-revision-comment-css' => '1ac25e8a',
|
||||
'differential-revision-comment-list-css' => '1ac25e8a',
|
||||
'differential-revision-detail-css' => '1ac25e8a',
|
||||
'differential-revision-history-css' => '1ac25e8a',
|
||||
'differential-table-of-contents-css' => '1ac25e8a',
|
||||
'differential-changeset-view-css' => '613cf273',
|
||||
'differential-core-view-css' => '613cf273',
|
||||
'differential-revision-add-comment-css' => '613cf273',
|
||||
'differential-revision-comment-css' => '613cf273',
|
||||
'differential-revision-comment-list-css' => '613cf273',
|
||||
'differential-revision-detail-css' => '613cf273',
|
||||
'differential-revision-history-css' => '613cf273',
|
||||
'differential-table-of-contents-css' => '613cf273',
|
||||
'diffusion-commit-view-css' => '03ef179e',
|
||||
'javelin-behavior' => 'd985d27a',
|
||||
'javelin-behavior' => 'db95a6d0',
|
||||
'javelin-behavior-aphront-basic-tokenizer' => '33f413ef',
|
||||
'javelin-behavior-differential-diff-radios' => 'ed383f69',
|
||||
'javelin-behavior-differential-edit-inline-comments' => 'ed383f69',
|
||||
|
@ -1121,22 +1134,22 @@ celerity_register_resource_map(array(
|
|||
'javelin-behavior-differential-populate' => 'ed383f69',
|
||||
'javelin-behavior-differential-show-more' => 'ed383f69',
|
||||
'javelin-behavior-workflow' => '122a6b6d',
|
||||
'javelin-dom' => 'd985d27a',
|
||||
'javelin-event' => 'd985d27a',
|
||||
'javelin-install' => 'd985d27a',
|
||||
'javelin-json' => 'd985d27a',
|
||||
'javelin-dom' => 'db95a6d0',
|
||||
'javelin-event' => 'db95a6d0',
|
||||
'javelin-install' => 'db95a6d0',
|
||||
'javelin-json' => 'db95a6d0',
|
||||
'javelin-mask' => '122a6b6d',
|
||||
'javelin-request' => 'd985d27a',
|
||||
'javelin-stratcom' => 'd985d27a',
|
||||
'javelin-request' => 'db95a6d0',
|
||||
'javelin-stratcom' => 'db95a6d0',
|
||||
'javelin-tokenizer' => '33f413ef',
|
||||
'javelin-typeahead' => '33f413ef',
|
||||
'javelin-typeahead-normalizer' => '33f413ef',
|
||||
'javelin-typeahead-ondemand-source' => '33f413ef',
|
||||
'javelin-typeahead-preloaded-source' => '33f413ef',
|
||||
'javelin-typeahead-source' => '33f413ef',
|
||||
'javelin-uri' => 'd985d27a',
|
||||
'javelin-util' => 'd985d27a',
|
||||
'javelin-vector' => 'd985d27a',
|
||||
'javelin-uri' => 'db95a6d0',
|
||||
'javelin-util' => 'db95a6d0',
|
||||
'javelin-vector' => 'db95a6d0',
|
||||
'javelin-workflow' => '122a6b6d',
|
||||
'phabricator-core-buttons-css' => 'a6102fe7',
|
||||
'phabricator-core-css' => 'a6102fe7',
|
||||
|
|
|
@ -410,6 +410,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorRemarkupRuleDiffusion' => 'infrastructure/markup/remarkup/markuprule/diffusion',
|
||||
'PhabricatorRemarkupRuleImageMacro' => 'infrastructure/markup/remarkup/markuprule/imagemacro',
|
||||
'PhabricatorRemarkupRuleManiphest' => 'infrastructure/markup/remarkup/markuprule/maniphest',
|
||||
'PhabricatorRemarkupRuleObjectName' => 'infrastructure/markup/remarkup/markuprule/objectname',
|
||||
'PhabricatorRemarkupRuleProxyImage' => 'infrastructure/markup/remarkup/markuprule/proxyimage',
|
||||
'PhabricatorRemarkupRuleYoutube' => 'infrastructure/markup/remarkup/markuprule/youtube',
|
||||
'PhabricatorRepository' => 'applications/repository/storage/repository',
|
||||
|
@ -841,10 +842,11 @@ phutil_register_library_map(array(
|
|||
'PhabricatorProjectProfile' => 'PhabricatorProjectDAO',
|
||||
'PhabricatorProjectProfileController' => 'PhabricatorProjectController',
|
||||
'PhabricatorRedirectController' => 'PhabricatorController',
|
||||
'PhabricatorRemarkupRuleDifferential' => 'PhutilRemarkupRule',
|
||||
'PhabricatorRemarkupRuleDifferential' => 'PhabricatorRemarkupRuleObjectName',
|
||||
'PhabricatorRemarkupRuleDiffusion' => 'PhutilRemarkupRule',
|
||||
'PhabricatorRemarkupRuleImageMacro' => 'PhutilRemarkupRule',
|
||||
'PhabricatorRemarkupRuleManiphest' => 'PhutilRemarkupRule',
|
||||
'PhabricatorRemarkupRuleManiphest' => 'PhabricatorRemarkupRuleObjectName',
|
||||
'PhabricatorRemarkupRuleObjectName' => 'PhutilRemarkupRule',
|
||||
'PhabricatorRemarkupRuleProxyImage' => 'PhutilRemarkupRule',
|
||||
'PhabricatorRemarkupRuleYoutube' => 'PhutilRemarkupRule',
|
||||
'PhabricatorRepository' => 'PhabricatorRepositoryDAO',
|
||||
|
|
|
@ -42,7 +42,7 @@ class PhabricatorLoginController extends PhabricatorAuthController {
|
|||
$error_view = null;
|
||||
if ($password_auth) {
|
||||
$error = false;
|
||||
$username = $request->getCookie('phusr');
|
||||
$username_or_email = $request->getCookie('phusr');
|
||||
if ($request->isFormPost()) {
|
||||
$username_or_email = $request->getStr('username_or_email');
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ final class DifferentialRevisionCommentView extends AphrontView {
|
|||
private $inlines;
|
||||
private $changesets;
|
||||
private $target;
|
||||
private $commentNumber;
|
||||
|
||||
public function setComment($comment) {
|
||||
$this->comment = $comment;
|
||||
|
@ -61,6 +62,11 @@ final class DifferentialRevisionCommentView extends AphrontView {
|
|||
$this->target = $target;
|
||||
}
|
||||
|
||||
public function setCommentNumber($comment_number) {
|
||||
$this->commentNumber = $comment_number;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function render() {
|
||||
|
||||
require_celerity_resource('phabricator-remarkup-css');
|
||||
|
@ -78,6 +84,24 @@ final class DifferentialRevisionCommentView extends AphrontView {
|
|||
$date = date('F jS, Y g:i:s A', $comment->getDateCreated());
|
||||
}
|
||||
|
||||
$info = array($date);
|
||||
|
||||
$comment_anchor = null;
|
||||
$num = $this->commentNumber;
|
||||
if ($num) {
|
||||
Javelin::initBehavior('phabricator-watch-anchor');
|
||||
$info[] = phutil_render_tag(
|
||||
'a',
|
||||
array(
|
||||
'name' => 'comment-'.$num,
|
||||
'href' => '#comment-'.$num,
|
||||
),
|
||||
'Comment D'.$comment->getRevisionID().'#'.$num);
|
||||
$comment_anchor = 'anchor-comment-'.$num;
|
||||
}
|
||||
|
||||
$info = implode(' · ', $info);
|
||||
|
||||
$author = $this->handles[$comment->getAuthorPHID()];
|
||||
$author_link = $author->renderLink();
|
||||
|
||||
|
@ -189,21 +213,25 @@ final class DifferentialRevisionCommentView extends AphrontView {
|
|||
$background = "background-image: url('{$uri}');";
|
||||
}
|
||||
|
||||
return
|
||||
'<div class="differential-comment '.$action_class.'">'.
|
||||
'<div class="differential-comment-head">'.
|
||||
'<div class="differential-comment-date">'.$date.'</div>'.
|
||||
'<div class="differential-comment-title">'.$title.'</div>'.
|
||||
'</div>'.
|
||||
'<div class="differential-comment-body" style="'.$background.'">'.
|
||||
'<div class="differential-comment-content">'.
|
||||
'<div class="differential-comment-core">'.
|
||||
$content.
|
||||
'</div>'.
|
||||
$inline_render.
|
||||
return phutil_render_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => "differential-comment {$action_class}",
|
||||
'id' => $comment_anchor,
|
||||
),
|
||||
'<div class="differential-comment-head">'.
|
||||
'<span class="differential-comment-info">'.$info.'</span>'.
|
||||
'<span class="differential-comment-title">'.$title.'</span>'.
|
||||
'<div style="clear: both;"></div>'.
|
||||
'</div>'.
|
||||
'<div class="differential-comment-body" style="'.$background.'">'.
|
||||
'<div class="differential-comment-content">'.
|
||||
'<div class="differential-comment-core">'.
|
||||
$content.
|
||||
'</div>'.
|
||||
$inline_render.
|
||||
'</div>'.
|
||||
'</div>';
|
||||
'</div>');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
phutil_require_module('phabricator', 'applications/differential/constants/action');
|
||||
phutil_require_module('phabricator', 'infrastructure/celerity/api');
|
||||
phutil_require_module('phabricator', 'infrastructure/javelin/api');
|
||||
phutil_require_module('phabricator', 'view/base');
|
||||
|
||||
phutil_require_module('phutil', 'markup');
|
||||
|
|
|
@ -63,7 +63,7 @@ final class DifferentialRevisionCommentListView extends AphrontView {
|
|||
|
||||
$inlines = mgroup($this->inlines, 'getCommentID');
|
||||
|
||||
|
||||
$num = 1;
|
||||
$html = array();
|
||||
foreach ($this->comments as $comment) {
|
||||
$view = new DifferentialRevisionCommentView();
|
||||
|
@ -73,6 +73,7 @@ final class DifferentialRevisionCommentListView extends AphrontView {
|
|||
$view->setInlineComments(idx($inlines, $comment->getID(), array()));
|
||||
$view->setChangesets($this->changesets);
|
||||
$view->setTargetDiff($this->target);
|
||||
$view->setCommentNumber($num++);
|
||||
|
||||
$html[] = $view->render();
|
||||
}
|
||||
|
@ -158,7 +159,7 @@ final class DifferentialRevisionCommentListView extends AphrontView {
|
|||
}
|
||||
|
||||
return
|
||||
'<div>'.
|
||||
'<div class="differential-comment-list">'.
|
||||
implode("\n", $header).
|
||||
$hidden.
|
||||
implode("\n", $visible).
|
||||
|
|
|
@ -23,6 +23,7 @@ class ManiphestTransactionDetailView extends AphrontView {
|
|||
private $markupEngine;
|
||||
private $forEmail;
|
||||
private $preview;
|
||||
private $commentNumber;
|
||||
|
||||
private $renderSummaryOnly;
|
||||
private $renderFullSummary;
|
||||
|
@ -65,6 +66,11 @@ class ManiphestTransactionDetailView extends AphrontView {
|
|||
return $this->renderFullSummary;
|
||||
}
|
||||
|
||||
public function setCommentNumber($comment_number) {
|
||||
$this->commentNumber = $comment_number;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function renderForEmail($with_date) {
|
||||
$this->forEmail = true;
|
||||
|
||||
|
@ -174,16 +180,37 @@ class ManiphestTransactionDetailView extends AphrontView {
|
|||
$timestamp = phabricator_format_timestamp($transaction->getDateCreated());
|
||||
}
|
||||
|
||||
$info = array();
|
||||
$info[] = $timestamp;
|
||||
|
||||
|
||||
$comment_anchor = null;
|
||||
$num = $this->commentNumber;
|
||||
if ($num) {
|
||||
Javelin::initBehavior('phabricator-watch-anchor');
|
||||
$info[] = javelin_render_tag(
|
||||
'a',
|
||||
array(
|
||||
'name' => 'comment-'.$num,
|
||||
'href' => '#comment-'.$num,
|
||||
),
|
||||
'Comment T'.$any_transaction->getTaskID().'#'.$num);
|
||||
$comment_anchor = 'anchor-comment-'.$num;
|
||||
}
|
||||
|
||||
$info = implode(' · ', $info);
|
||||
|
||||
return phutil_render_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => "maniphest-transaction-detail-container",
|
||||
'class' => "maniphest-transaction-detail-container",
|
||||
'style' => "background-image: url('".$author->getImageURI()."')",
|
||||
'id' => $comment_anchor,
|
||||
),
|
||||
'<div class="maniphest-transaction-detail-view '.$more_classes.'">'.
|
||||
'<div class="maniphest-transaction-header">'.
|
||||
'<div class="maniphest-transaction-timestamp">'.
|
||||
$timestamp.
|
||||
$info.
|
||||
'</div>'.
|
||||
$descs.
|
||||
'</div>'.
|
||||
|
|
|
@ -77,17 +77,19 @@ class ManiphestTransactionListView extends AphrontView {
|
|||
$groups[] = $group;
|
||||
}
|
||||
|
||||
$sequence = 1;
|
||||
foreach ($groups as $group) {
|
||||
$view = new ManiphestTransactionDetailView();
|
||||
$view->setTransactionGroup($group);
|
||||
$view->setHandles($this->handles);
|
||||
$view->setMarkupEngine($this->markupEngine);
|
||||
$view->setPreview($this->preview);
|
||||
$view->setCommentNumber($sequence++);
|
||||
$views[] = $view->render();
|
||||
}
|
||||
|
||||
return
|
||||
'<div style="padding: .5em 1.5em;">'.
|
||||
'<div class="maniphest-transaction-list-view">'.
|
||||
implode("\n", $views).
|
||||
'</div>';
|
||||
}
|
||||
|
|
|
@ -98,6 +98,10 @@ by mentioning the name of an object:
|
|||
# You must specify at least 7 characters of the hash.
|
||||
T123 # Link to Maniphest task T123
|
||||
|
||||
You can also link directly to a comment in Maniphest and Differential:
|
||||
|
||||
T123#4 # Link to comment #4 of T123
|
||||
|
||||
= Quoting Text =
|
||||
|
||||
To quote text, preface it with an ">":
|
||||
|
|
|
@ -43,9 +43,22 @@ final class CelerityStaticResourceResponse {
|
|||
return $this->metadataBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a behavior for initialization. NOTE: if $config is empty,
|
||||
* a behavior will execute only once even if it is initialized multiple times.
|
||||
* If $config is nonempty, the behavior will be invoked once for each config.
|
||||
*/
|
||||
public function initBehavior($behavior, array $config = array()) {
|
||||
$this->requireResource('javelin-behavior-'.$behavior);
|
||||
$this->behaviors[$behavior][] = $config;
|
||||
|
||||
if (empty($this->behaviors[$behavior])) {
|
||||
$this->behaviors[$behavior] = array();
|
||||
}
|
||||
|
||||
if ($config) {
|
||||
$this->behaviors[$behavior][] = $config;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,18 +20,10 @@
|
|||
* @group markup
|
||||
*/
|
||||
class PhabricatorRemarkupRuleDifferential
|
||||
extends PhutilRemarkupRule {
|
||||
extends PhabricatorRemarkupRuleObjectName {
|
||||
|
||||
public function apply($text) {
|
||||
return preg_replace_callback(
|
||||
'@\bD(\d+)\b@',
|
||||
array($this, 'markupDifferentialLink'),
|
||||
$text);
|
||||
}
|
||||
|
||||
public function markupDifferentialLink($matches) {
|
||||
return $this->getEngine()->storeText(
|
||||
'<a href="/D'.$matches[1].'">D'.$matches[1].'</a>');
|
||||
protected function getObjectNamePrefix() {
|
||||
return 'D';
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
|
||||
|
||||
phutil_require_module('phutil', 'markup/engine/remarkup/markuprule/base');
|
||||
phutil_require_module('phabricator', 'infrastructure/markup/remarkup/markuprule/objectname');
|
||||
|
||||
|
||||
phutil_require_source('PhabricatorRemarkupRuleDifferential.php');
|
||||
|
|
|
@ -20,18 +20,10 @@
|
|||
* @group markup
|
||||
*/
|
||||
class PhabricatorRemarkupRuleManiphest
|
||||
extends PhutilRemarkupRule {
|
||||
extends PhabricatorRemarkupRuleObjectName {
|
||||
|
||||
public function apply($text) {
|
||||
return preg_replace_callback(
|
||||
'@\bT(\d+)\b@',
|
||||
array($this, 'markupManiphestLink'),
|
||||
$text);
|
||||
}
|
||||
|
||||
public function markupManiphestLink($matches) {
|
||||
return $this->getEngine()->storeText(
|
||||
'<a href="/T'.$matches[1].'">T'.$matches[1].'</a>');
|
||||
protected function getObjectNamePrefix() {
|
||||
return 'T';
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
|
||||
|
||||
phutil_require_module('phutil', 'markup/engine/remarkup/markuprule/base');
|
||||
phutil_require_module('phabricator', 'infrastructure/markup/remarkup/markuprule/objectname');
|
||||
|
||||
|
||||
phutil_require_source('PhabricatorRemarkupRuleManiphest.php');
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group markup
|
||||
*/
|
||||
abstract class PhabricatorRemarkupRuleObjectName
|
||||
extends PhutilRemarkupRule {
|
||||
|
||||
abstract protected function getObjectNamePrefix();
|
||||
|
||||
public function apply($text) {
|
||||
$prefix = $this->getObjectNamePrefix();
|
||||
return preg_replace_callback(
|
||||
"@\b{$prefix}(\d+)(?:#(\d+))?\b@",
|
||||
array($this, 'markupObjectNameLink'),
|
||||
$text);
|
||||
}
|
||||
|
||||
public function markupObjectNameLink($matches) {
|
||||
$prefix = $this->getObjectNamePrefix();
|
||||
$id = $matches[1];
|
||||
|
||||
if (isset($matches[2])) {
|
||||
$comment_id = $matches[2];
|
||||
$href = "/{$prefix}{$id}#comment-{$comment_id}";
|
||||
$text = "{$prefix}{$id}#{$comment_id}";
|
||||
} else {
|
||||
$href = "/{$prefix}{$id}";
|
||||
$text = "{$prefix}{$id}";
|
||||
}
|
||||
|
||||
return $this->getEngine()->storeText(
|
||||
phutil_render_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $href,
|
||||
),
|
||||
$text));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('phutil', 'markup');
|
||||
phutil_require_module('phutil', 'markup/engine/remarkup/markuprule/base');
|
||||
|
||||
|
||||
phutil_require_source('PhabricatorRemarkupRuleObjectName.php');
|
|
@ -65,14 +65,7 @@ final class AphrontFormView extends AphrontView {
|
|||
public function render() {
|
||||
require_celerity_resource('aphront-form-view-css');
|
||||
|
||||
static $initialized_behavior;
|
||||
if (!$initialized_behavior) {
|
||||
// TODO: This is sort of a yucky hack.
|
||||
$initialized_behavior = true;
|
||||
Javelin::initBehavior(
|
||||
'aphront-form-disable-on-submit',
|
||||
array());
|
||||
}
|
||||
Javelin::initBehavior('aphront-form-disable-on-submit');
|
||||
|
||||
return javelin_render_tag(
|
||||
'form',
|
||||
|
|
|
@ -3,14 +3,29 @@
|
|||
*/
|
||||
|
||||
|
||||
.differential-comment-date {
|
||||
.differential-comment {
|
||||
padding: 3px 6px;
|
||||
margin-bottom: 10px;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
.differential-comment-list .anchor-target {
|
||||
background-color: #ffffdd;
|
||||
border-color: #ffff00;
|
||||
}
|
||||
|
||||
.differential-comment-info {
|
||||
color: #666666;
|
||||
float: right;
|
||||
font-size: 11px;
|
||||
margin: 0em;
|
||||
margin: 0 0 3px;
|
||||
padding-top: 6px;
|
||||
}
|
||||
|
||||
.differential-comment-info a {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.differential-comment-title {
|
||||
font-weight: bold;
|
||||
height: 16px;
|
||||
|
@ -24,7 +39,6 @@
|
|||
padding-left: 62px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 6px 0px;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.differential-comment-content {
|
||||
|
|
|
@ -2,10 +2,21 @@
|
|||
* @provides maniphest-transaction-detail-css
|
||||
*/
|
||||
|
||||
.maniphest-trnasaction-list-view {
|
||||
padding: .5em 1.5em;
|
||||
}
|
||||
|
||||
.maniphest-transaction-detail-container {
|
||||
margin: 1em 1em 1.5em;
|
||||
background: 0px 0px no-repeat;
|
||||
margin: 1em 1em 1.25em;
|
||||
background: 2px 2px no-repeat;
|
||||
min-height: 50px;
|
||||
padding: 2px 2px;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
.maniphest-transaction-list-view .anchor-target {
|
||||
background-color: #ffffdd;
|
||||
border-color: #ffff00;
|
||||
}
|
||||
|
||||
.maniphest-transaction-detail-container .upforgrab {
|
||||
|
|
34
webroot/rsrc/js/application/core/behavior-watch-anchor.js
Normal file
34
webroot/rsrc/js/application/core/behavior-watch-anchor.js
Normal file
|
@ -0,0 +1,34 @@
|
|||
/**
|
||||
* @provides javelin-behavior-phabricator-watch-anchor
|
||||
* @requires javelin-behavior
|
||||
* javelin-stratcom
|
||||
* javelin-util
|
||||
* javelin-dom
|
||||
*/
|
||||
|
||||
JX.behavior('phabricator-watch-anchor', function() {
|
||||
|
||||
var highlighted;
|
||||
|
||||
function highlight() {
|
||||
highlighted && JX.DOM.alterClass(highlighted, 'anchor-target', false);
|
||||
try {
|
||||
highlighted = JX.$('anchor-' + window.location.hash.replace('#', ''));
|
||||
JX.DOM.alterClass(highlighted, 'anchor-target', true);
|
||||
} catch (ex) {
|
||||
if (ex === JX.$.NotFound) {
|
||||
highlighted = null;
|
||||
} else {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JX.Stratcom.listen(
|
||||
'hashchange',
|
||||
null,
|
||||
// Defer invocation so other listeners can update the document.
|
||||
function() { JX.defer(highlight); });
|
||||
|
||||
JX.defer(highlight);
|
||||
});
|
|
@ -7,13 +7,43 @@
|
|||
|
||||
JX.behavior('differential-show-all-comments', function(config) {
|
||||
|
||||
var shown = false;
|
||||
function reveal(node) {
|
||||
if (shown) {
|
||||
return;
|
||||
}
|
||||
shown = true;
|
||||
node = node || JX.DOM.find(
|
||||
document.body,
|
||||
'div',
|
||||
'differential-all-comments-container');
|
||||
if (node) {
|
||||
JX.DOM.setContent(node, JX.$H(config.markup));
|
||||
}
|
||||
}
|
||||
|
||||
// Reveal the hidden comments if the user clicks "Show All Comments", or if
|
||||
// there's an anchor in the URL, since we don't want to link to "#comment-3"
|
||||
// and have it collapsed.
|
||||
|
||||
if (window.location.hash) {
|
||||
reveal();
|
||||
} else {
|
||||
JX.Stratcom.listen(
|
||||
'hashchange',
|
||||
null,
|
||||
function(e) {
|
||||
if (window.location.hash.match(/comment/)) {
|
||||
reveal();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
JX.Stratcom.listen(
|
||||
'click',
|
||||
'differential-show-all-comments',
|
||||
function(e) {
|
||||
JX.DOM.setContent(
|
||||
e.getNode('differential-all-comments-container'),
|
||||
JX.$H(config.markup));
|
||||
reveal(e.getNode('differential-all-comments-container'));
|
||||
e.kill();
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in a new issue