1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-22 23:02:42 +01:00

InlineComments

This commit is contained in:
epriestley 2011-02-01 16:42:36 -08:00
parent 9dac0ed9f1
commit 246cba2bf0
18 changed files with 495 additions and 96 deletions

View file

@ -9,7 +9,7 @@
celerity_register_resource_map(array( celerity_register_resource_map(array(
'aphront-dialog-view-css' => 'aphront-dialog-view-css' =>
array( array(
'uri' => '/res/d98e6292/rsrc/css/aphront/dialog-view.css', 'uri' => '/res/a05107ae/rsrc/css/aphront/dialog-view.css',
'type' => 'css', 'type' => 'css',
'requires' => 'requires' =>
array( array(
@ -100,7 +100,7 @@ celerity_register_resource_map(array(
), ),
'differential-changeset-view-css' => 'differential-changeset-view-css' =>
array( array(
'uri' => '/res/658d181a/rsrc/css/application/differential/changeset-view.css', 'uri' => '/res/11e7232a/rsrc/css/application/differential/changeset-view.css',
'type' => 'css', 'type' => 'css',
'requires' => 'requires' =>
array( array(
@ -190,7 +190,7 @@ celerity_register_resource_map(array(
), ),
'phabricator-core-dialog-css' => 'phabricator-core-dialog-css' =>
array( array(
'uri' => '/res/d9580553/rsrc/css/core/dialog.css', 'uri' => '/res/f66cec41/rsrc/css/core/dialog.css',
'type' => 'css', 'type' => 'css',
'requires' => 'requires' =>
array( array(
@ -237,7 +237,7 @@ celerity_register_resource_map(array(
), ),
'javelin-behavior-differential-edit-inline-comments' => 'javelin-behavior-differential-edit-inline-comments' =>
array( array(
'uri' => '/res/51d7da98/rsrc/js/application/differential/behavior-edit-inline-comments.js', 'uri' => '/res/be5ed33e/rsrc/js/application/differential/behavior-edit-inline-comments.js',
'type' => 'js', 'type' => 'js',
'requires' => 'requires' =>
array( array(
@ -276,7 +276,7 @@ celerity_register_resource_map(array(
), ),
'javelin-init-prod' => 'javelin-init-prod' =>
array( array(
'uri' => '/res/ce6bff38/rsrc/js/javelin/init.min.js', 'uri' => '/res/1267c868/rsrc/js/javelin/init.min.js',
'type' => 'js', 'type' => 'js',
'requires' => 'requires' =>
array( array(
@ -285,7 +285,7 @@ celerity_register_resource_map(array(
), ),
'javelin-lib-dev' => 'javelin-lib-dev' =>
array( array(
'uri' => '/res/29c9b6b4/rsrc/js/javelin/javelin.dev.js', 'uri' => '/res/53784c9a/rsrc/js/javelin/javelin.dev.js',
'type' => 'js', 'type' => 'js',
'requires' => 'requires' =>
array( array(
@ -294,7 +294,7 @@ celerity_register_resource_map(array(
), ),
'javelin-lib-prod' => 'javelin-lib-prod' =>
array( array(
'uri' => '/res/ef13c830/rsrc/js/javelin/javelin.min.js', 'uri' => '/res/2f2b3b2e/rsrc/js/javelin/javelin.min.js',
'type' => 'js', 'type' => 'js',
'requires' => 'requires' =>
array( array(
@ -312,7 +312,7 @@ celerity_register_resource_map(array(
), ),
'javelin-typeahead-prod' => 'javelin-typeahead-prod' =>
array( array(
'uri' => '/res/593d9bb8/rsrc/js/javelin/typeahead.min.js', 'uri' => '/res/69d5fad1/rsrc/js/javelin/typeahead.min.js',
'type' => 'js', 'type' => 'js',
'requires' => 'requires' =>
array( array(
@ -321,7 +321,7 @@ celerity_register_resource_map(array(
), ),
'javelin-workflow-dev' => 'javelin-workflow-dev' =>
array( array(
'uri' => '/res/2d740661/rsrc/js/javelin/workflow.dev.js', 'uri' => '/res/7e690e16/rsrc/js/javelin/workflow.dev.js',
'type' => 'js', 'type' => 'js',
'requires' => 'requires' =>
array( array(
@ -340,7 +340,7 @@ celerity_register_resource_map(array(
), array ( ), array (
'packages' => 'packages' =>
array ( array (
'dc2390af' => '4bb7e37f' =>
array ( array (
'name' => 'core.pkg.css', 'name' => 'core.pkg.css',
'symbols' => 'symbols' =>
@ -357,10 +357,10 @@ celerity_register_resource_map(array(
9 => 'aphront-typeahead-control-css', 9 => 'aphront-typeahead-control-css',
10 => 'phabricator-directory-css', 10 => 'phabricator-directory-css',
), ),
'uri' => '/res/pkg/dc2390af/core.pkg.css', 'uri' => '/res/pkg/4bb7e37f/core.pkg.css',
'type' => 'css', 'type' => 'css',
), ),
'69b11588' => 'f399aad7' =>
array ( array (
'name' => 'differential.pkg.css', 'name' => 'differential.pkg.css',
'symbols' => 'symbols' =>
@ -371,27 +371,27 @@ celerity_register_resource_map(array(
3 => 'differential-revision-history-css', 3 => 'differential-revision-history-css',
4 => 'differential-table-of-contents-css', 4 => 'differential-table-of-contents-css',
), ),
'uri' => '/res/pkg/69b11588/differential.pkg.css', 'uri' => '/res/pkg/f399aad7/differential.pkg.css',
'type' => 'css', 'type' => 'css',
), ),
), ),
'reverse' => 'reverse' =>
array ( array (
'phabricator-core-css' => 'dc2390af', 'phabricator-core-css' => '4bb7e37f',
'phabricator-core-buttons-css' => 'dc2390af', 'phabricator-core-buttons-css' => '4bb7e37f',
'phabricator-standard-page-view' => 'dc2390af', 'phabricator-standard-page-view' => '4bb7e37f',
'aphront-dialog-view-css' => 'dc2390af', 'aphront-dialog-view-css' => '4bb7e37f',
'aphront-form-view-css' => 'dc2390af', 'aphront-form-view-css' => '4bb7e37f',
'aphront-panel-view-css' => 'dc2390af', 'aphront-panel-view-css' => '4bb7e37f',
'aphront-side-nav-view-css' => 'dc2390af', 'aphront-side-nav-view-css' => '4bb7e37f',
'aphront-table-view-css' => 'dc2390af', 'aphront-table-view-css' => '4bb7e37f',
'aphront-tokenizer-control-css' => 'dc2390af', 'aphront-tokenizer-control-css' => '4bb7e37f',
'aphront-typeahead-control-css' => 'dc2390af', 'aphront-typeahead-control-css' => '4bb7e37f',
'phabricator-directory-css' => 'dc2390af', 'phabricator-directory-css' => '4bb7e37f',
'differential-core-view-css' => '69b11588', 'differential-core-view-css' => 'f399aad7',
'differential-changeset-view-css' => '69b11588', 'differential-changeset-view-css' => 'f399aad7',
'differential-revision-detail-css' => '69b11588', 'differential-revision-detail-css' => 'f399aad7',
'differential-revision-history-css' => '69b11588', 'differential-revision-history-css' => 'f399aad7',
'differential-table-of-contents-css' => '69b11588', 'differential-table-of-contents-css' => 'f399aad7',
), ),
)); ));

View file

@ -91,6 +91,8 @@ phutil_register_library_map(array(
'DifferentialDiffViewController' => 'applications/differential/controller/diffview', 'DifferentialDiffViewController' => 'applications/differential/controller/diffview',
'DifferentialHunk' => 'applications/differential/storage/hunk', 'DifferentialHunk' => 'applications/differential/storage/hunk',
'DifferentialInlineComment' => 'applications/differential/storage/inlinecomment', 'DifferentialInlineComment' => 'applications/differential/storage/inlinecomment',
'DifferentialInlineCommentEditController' => 'applications/differential/controller/inlinecommentedit',
'DifferentialInlineCommentView' => 'applications/differential/view/inlinecomment',
'DifferentialLintStatus' => 'applications/differential/constants/lintstatus', 'DifferentialLintStatus' => 'applications/differential/constants/lintstatus',
'DifferentialMail' => 'applications/differential/mail/base', 'DifferentialMail' => 'applications/differential/mail/base',
'DifferentialMarkupEngineFactory' => 'applications/differential/parser/markup', 'DifferentialMarkupEngineFactory' => 'applications/differential/parser/markup',
@ -266,6 +268,8 @@ phutil_register_library_map(array(
'DifferentialDiffViewController' => 'DifferentialController', 'DifferentialDiffViewController' => 'DifferentialController',
'DifferentialHunk' => 'DifferentialDAO', 'DifferentialHunk' => 'DifferentialDAO',
'DifferentialInlineComment' => 'DifferentialDAO', 'DifferentialInlineComment' => 'DifferentialDAO',
'DifferentialInlineCommentEditController' => 'DifferentialController',
'DifferentialInlineCommentView' => 'AphrontView',
'DifferentialNewDiffMail' => 'DifferentialReviewRequestMail', 'DifferentialNewDiffMail' => 'DifferentialReviewRequestMail',
'DifferentialReviewRequestMail' => 'DifferentialMail', 'DifferentialReviewRequestMail' => 'DifferentialMail',
'DifferentialRevision' => 'DifferentialDAO', 'DifferentialRevision' => 'DifferentialDAO',

View file

@ -91,7 +91,7 @@ class AphrontDefaultApplicationConfiguration
'save/$' => 'DifferentialCommentSaveController', 'save/$' => 'DifferentialCommentSaveController',
'inline/' => array( 'inline/' => array(
'preview/$' => 'DifferentialInlineCommentPreviewController', 'preview/$' => 'DifferentialInlineCommentPreviewController',
'edit/$' => 'DifferentialInlineCommentEditController', 'edit/(?<id>\d+)/$' => 'DifferentialInlineCommentEditController',
), ),
), ),
), ),
@ -166,6 +166,11 @@ class AphrontDefaultApplicationConfiguration
$response = new AphrontWebpageResponse(); $response = new AphrontWebpageResponse();
$response->setContent($view->render()); $response->setContent($view->render());
return $response; return $response;
} else {
return id(new AphrontAjaxResponse())
->setContent(array(
'dialog' => $response->buildResponseString(),
));
} }
} else if ($response instanceof Aphront404Response) { } else if ($response instanceof Aphront404Response) {

View file

@ -8,12 +8,14 @@
phutil_require_module('phabricator', 'aphront/applicationconfiguration'); phutil_require_module('phabricator', 'aphront/applicationconfiguration');
phutil_require_module('phabricator', 'aphront/request'); phutil_require_module('phabricator', 'aphront/request');
phutil_require_module('phabricator', 'aphront/response/ajax');
phutil_require_module('phabricator', 'aphront/response/webpage'); phutil_require_module('phabricator', 'aphront/response/webpage');
phutil_require_module('phabricator', 'applications/base/controller/404'); phutil_require_module('phabricator', 'applications/base/controller/404');
phutil_require_module('phabricator', 'view/page/failure'); phutil_require_module('phabricator', 'view/page/failure');
phutil_require_module('phabricator', 'view/page/standard'); phutil_require_module('phabricator', 'view/page/standard');
phutil_require_module('phutil', 'markup'); phutil_require_module('phutil', 'markup');
phutil_require_module('phutil', 'utils');
phutil_require_source('AphrontDefaultApplicationConfiguration.php'); phutil_require_source('AphrontDefaultApplicationConfiguration.php');

View file

@ -23,6 +23,7 @@ class DifferentialChangesetViewController extends DifferentialController {
$request = $this->getRequest(); $request = $this->getRequest();
$id = $request->getStr('id'); $id = $request->getStr('id');
$author_phid = $request->getUser()->getPHID();
$changeset = id(new DifferentialChangeset())->load($id); $changeset = id(new DifferentialChangeset())->load($id);
if (!$changeset) { if (!$changeset) {
@ -54,6 +55,22 @@ class DifferentialChangesetViewController extends DifferentialController {
$parser = new DifferentialChangesetParser(); $parser = new DifferentialChangesetParser();
$parser->setChangeset($changeset); $parser->setChangeset($changeset);
$phids = array();
$inlines = $this->loadInlineComments($id, $author_phid);
foreach ($inlines as $inline) {
$parser->parseInlineComment($inline);
$phids[$inline->getAuthorPHID()] = true;
}
$phids = array_keys($phids);
$handles = id(new PhabricatorObjectHandleData($phids))
->loadHandles();
$parser->setHandles($handles);
$factory = new DifferentialMarkupEngineFactory();
$engine = $factory->newDifferentialCommentMarkupEngine();
$parser->setMarkupEngine($engine);
$output = $parser->render(null, $range_s, $range_e, $mask); $output = $parser->render(null, $range_s, $range_e, $mask);
if ($request->isAjax()) { if ($request->isAjax()) {
@ -85,4 +102,12 @@ class DifferentialChangesetViewController extends DifferentialController {
)); ));
} }
private function loadInlineComments($changeset_id, $author_phid) {
return id(new DifferentialInlineComment())->loadAllWhere(
'changesetID = %d AND (commentID IS NOT NULL OR authorPHID = %s)',
$changeset_id,
$author_phid);
}
} }

View file

@ -0,0 +1,116 @@
<?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.
*/
class DifferentialInlineCommentEditController extends DifferentialController {
private $revisionID;
public function willProcessRequest(array $data) {
$this->revisionID = $data['id'];
}
public function processRequest() {
$request = $this->getRequest();
$changeset = $request->getInt('changeset');
$is_new = $request->getInt('is_new');
$on_right = $request->getInt('on_right');
$number = $request->getInt('number');
$length = $request->getInt('length');
$text = $request->getStr('text');
$op = $request->getStr('op');
$user = $request->getUser();
$submit_uri = '/differential/comment/inline/edit/'.$this->revisionID.'/';
switch ($op) {
case 'delete':
if ($request->isFormPost()) {
// do the delete;
return new AphrontAjaxResponse();
}
$dialog = new AphrontDialogView();
$dialog->setTitle('Really delete this comment?');
return id(new AphrontDialogResponse())->setDialog($dialog);
case 'edit':
$dialog = new AphrontDialogView();
return id(new AphrontDialogResponse())->setDialog($dialog);
case 'create':
if (!$request->isFormPost() || !strlen($text)) {
return new AphrontAjaxResponse();
}
$factory = new DifferentialMarkupEngineFactory();
$engine = $factory->newDifferentialCommentMarkupEngine();
$phids = array($user->getPHID());
$handles = id(new PhabricatorObjectHandleData($phids))
->loadHandles();
$inline = id(new DifferentialInlineComment())
->setRevisionID($this->revisionID)
->setChangesetID($changeset)
->setCommentID(null)
->setAuthorPHID($user->getPHID())
->setLineNumber($number)
->setLineLength($length)
->setIsNewFile($is_new)
->setContent($text)
->save();
$view = new DifferentialInlineCommentView();
$view->setInlineComment($inline);
$view->setOnRight($on_right);
$view->setBuildScaffolding(true);
$view->setMarkupEngine($engine);
$view->setHandles($handles);
return id(new AphrontAjaxResponse())
->setContent(
array(
'inlineCommentID' => $inline->getID(),
'markup' => $view->render(),
));
default:
$dialog = new AphrontDialogView();
$dialog->setUser($user);
$dialog->setTitle('New Inline Comment');
$dialog->setSubmitURI($submit_uri);
$dialog->addHiddenInput('op', 'create');
$dialog->addHiddenInput('changeset', $changeset);
$dialog->addHiddenInput('is_new', $is_new);
$dialog->addHiddenInput('on_right', $on_right);
$dialog->addHiddenInput('number', $number);
$dialog->addHiddenInput('length', $length);
$dialog->addSubmitButton();
$dialog->addCancelButton('#');
$dialog->appendChild('<textarea name="text"></textarea>');
return id(new AphrontDialogResponse())->setDialog($dialog);
}
}
}

View file

@ -0,0 +1,19 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'aphront/response/ajax');
phutil_require_module('phabricator', 'aphront/response/dialog');
phutil_require_module('phabricator', 'applications/differential/controller/base');
phutil_require_module('phabricator', 'applications/differential/storage/inlinecomment');
phutil_require_module('phabricator', 'applications/differential/view/inlinecomment');
phutil_require_module('phabricator', 'view/dialog');
phutil_require_module('phutil', 'utils');
phutil_require_source('DifferentialInlineCommentEditController.php');

View file

@ -42,6 +42,8 @@ class DifferentialChangesetParser {
protected $oldChangesetID = null; protected $oldChangesetID = null;
protected $noHighlight; protected $noHighlight;
private $handles;
const CACHE_VERSION = 4; const CACHE_VERSION = 4;
const ATTR_GENERATED = 'attr:generated'; const ATTR_GENERATED = 'attr:generated';
@ -91,6 +93,16 @@ class DifferentialChangesetParser {
} }
} }
public function setHandles(array $handles) {
$this->handles = $handles;
return $this;
}
public function setMarkupEngine(PhutilMarkupEngine $engine) {
$this->markupEngine = $engine;
return $this;
}
public function parseHunk(DifferentialHunk $hunk) { public function parseHunk(DifferentialHunk $hunk) {
$this->parsedHunk = true; $this->parsedHunk = true;
$lines = $hunk->getChanges(); $lines = $hunk->getChanges();
@ -773,11 +785,12 @@ EOSYNTHETIC;
$new_mask = array(); $new_mask = array();
$feedback_mask = array(); $feedback_mask = array();
$handles = array();
if ($this->comments) { if ($this->comments) {
foreach ($this->comments as $comment) { foreach ($this->comments as $comment) {
$start = max($comment->getLineNumber() - self::LINES_CONTEXT, 0); $start = max($comment->getLineNumber() - self::LINES_CONTEXT, 0);
$end = $comment->getFinalLine() + self::LINES_CONTEXT; $end = $comment->getLineNumber() +
$comment->getLineLength() +
self::LINES_CONTEXT;
$new = $this->isCommentInNewFile($comment); $new = $this->isCommentInNewFile($comment);
for ($ii = $start; $ii <= $end; $ii++) { for ($ii = $start; $ii <= $end; $ii++) {
if ($new) { if ($new) {
@ -799,22 +812,16 @@ EOSYNTHETIC;
$feedback_mask[$ii] = true; $feedback_mask[$ii] = true;
} }
} }
/*
$handle_ids = mpull($this->comments, 'getUserPHID');
$handles = array();
$handle_data = new ToolsHandleData($handle_ids, $handles);
$handle_data->needNames();
prep($handle_data);
$this->comments = msort($this->comments, 'getID'); $this->comments = msort($this->comments, 'getID');
foreach ($this->comments as $comment) { foreach ($this->comments as $comment) {
$final = $comment->getLineNumber() +
$comment->getLineLength();
if ($this->isCommentInNewFile($comment)) { if ($this->isCommentInNewFile($comment)) {
$new_comments[$comment->getFinalLine()][] = $comment; $new_comments[$final][] = $comment;
} else { } else {
$old_comments[$comment->getFinalLine()][] = $comment; $old_comments[$final][] = $comment;
} }
} }
*/
} }
$html = $this->renderTextChange( $html = $this->renderTextChange(
@ -823,7 +830,6 @@ EOSYNTHETIC;
$mask_force, $mask_force,
$feedback_mask, $feedback_mask,
$viewer_context, $viewer_context,
$handles,
$old_comments, $old_comments,
$new_comments); $new_comments);
@ -879,7 +885,6 @@ EOSYNTHETIC;
$mask_force, $mask_force,
$feedback_mask, $feedback_mask,
$viewer_context, $viewer_context,
$handles,
array $old_comments, array $old_comments,
array $new_comments) { array $new_comments) {
@ -1080,8 +1085,7 @@ EOSYNTHETIC;
foreach ($old_comments[$o_num] as $comment) { foreach ($old_comments[$o_num] as $comment) {
$xhp = $this->renderInlineComment( $xhp = $this->renderInlineComment(
$comment, $comment,
$viewer_context, $viewer_context);
$handles);
$html[] = $html[] =
'<tr class="inline"><th /><td>'. '<tr class="inline"><th /><td>'.
$xhp. $xhp.
@ -1092,8 +1096,7 @@ EOSYNTHETIC;
foreach ($new_comments[$n_num] as $comment) { foreach ($new_comments[$n_num] as $comment) {
$xhp = $this->renderInlineComment( $xhp = $this->renderInlineComment(
$comment, $comment,
$viewer_context, $viewer_context);
$handles);
$html[] = $html[] =
'<tr class="inline"><th /><td /><th /><td>'. '<tr class="inline"><th /><td /><th /><td>'.
$xhp. $xhp.
@ -1107,23 +1110,20 @@ EOSYNTHETIC;
private function renderInlineComment( private function renderInlineComment(
DifferentialInlineComment $comment, DifferentialInlineComment $comment,
$viewer_context, $viewer_context) {
$handles) {
$edit = $viewer_context && $edit = $viewer_context &&
($comment->getUserPHID() == $viewer_context->getUserID()) && ($comment->getAuthorPHID() == $viewer_context->getUserID()) &&
(!$comment->getFeedbackID()); (!$comment->getFeedbackID());
$is_new = $this->isCommentInNewFile($comment); $is_new = $this->isCommentInNewFile($comment);
return ''; return id(new DifferentialInlineCommentView())
/* ->setInlineComment($comment)
return <differential:inline-comment ->setOnRight($is_new)
inline={$comment} ->setHandles($this->handles)
edit={$edit} ->setMarkupEngine($this->markupEngine)
isnew={$is_new} ->render();
handle={$handles[$comment->getUserPHID()]} />;
*/
} }
protected function renderPropertyChangeHeader($changeset) { protected function renderPropertyChangeHeader($changeset) {
@ -1146,6 +1146,8 @@ EOSYNTHETIC;
return null; return null;
/* /*
TODO
$table = <table class="differential-property-table" />; $table = <table class="differential-property-table" />;
$table->appendChild( $table->appendChild(
<tr class="property-table-header"> <tr class="property-table-header">

View file

@ -48,6 +48,10 @@ class DifferentialChangesetDetailView extends AphrontView {
'div', 'div',
array( array(
'sigil' => 'differential-changeset', 'sigil' => 'differential-changeset',
'meta' => array(
'left' => $this->changeset->getID(),
'right' => $this->changeset->getID(),
),
'class' => $class, 'class' => $class,
), ),
'<a name="#'."TODO".'"></a>'. '<a name="#'."TODO".'"></a>'.

View file

@ -121,7 +121,7 @@ class DifferentialChangesetListView extends AphrontView {
if ($this->editable) { if ($this->editable) {
$revision = $this->revision; $revision = $this->revision;
Javelin::initBehavior('differential-edit-inline-comments', array( Javelin::initBehavior('differential-edit-inline-comments', array(
'uri' => '/differential/inline/edit/'.$revision->getID().'/', 'uri' => '/differential/comment/inline/edit/'.$revision->getID().'/',
)); ));
} }

View file

@ -0,0 +1,131 @@
<?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.
*/
final class DifferentialInlineCommentView extends AphrontView {
private $inlineComment;
private $onRight;
private $buildScaffolding;
private $handles;
private $markupEngine;
public function setInlineComment(DifferentialInlineComment $comment) {
$this->inlineComment = $comment;
return $this;
}
public function setOnRight($on_right) {
$this->onRight = $on_right;
return $this;
}
public function setBuildScaffolding($scaffold) {
$this->buildScaffolding = $scaffold;
return $this;
}
public function setHandles(array $handles) {
$this->handles = $handles;
return $this;
}
public function setMarkupEngine(PhutilMarkupEngine $engine) {
$this->markupEngine = $engine;
return $this;
}
public function render() {
$inline = $this->inlineComment;
$start = $inline->getLineNumber();
$length = $inline->getLineLength();
if ($length) {
$end = $start + $length;
$line = 'Lines '.number_format($start).'-'.number_format($end);
} else {
$line = 'Line '.number_format($start);
}
$metadata = array(
'number' => $inline->getLineNumber(),
'length' => $inline->getLineLength(),
'on_right' => $this->onRight, // TODO
);
$sigil = 'differential-inline-comment';
$links = 'xxx';
$content = $inline->getContent();
$handles = $this->handles;
if ($links) {
$links =
'<span class="differential-inline-comment-links">'.
$links.
'</span>';
}
$content = $this->markupEngine->markupText($content);
$markup = javelin_render_tag(
'div',
array(
'class' => 'differential-inline-comment',
'sigil' => $sigil,
'meta' => $metadata,
),
'<div class="differential-inline-comment-head">'.
$links.
'<span class="differential-inline-comment-line">'.$line.'</span>'.
$handles[$inline->getAuthorPHID()]->renderLink().
'</div>'.
$content);
return $this->scaffoldMarkup($markup);
}
private function scaffoldMarkup($markup) {
if (!$this->buildScaffolding) {
return $markup;
}
if ($this->onRight) {
return
'<table>'.
'<tr>'.
'<th></th>'.
'<td></td>'.
'<th></th>'.
'<td>'.$markup.'</td>'.
'</tr>'.
'</table>';
} else {
return
'<table>'.
'<tr>'.
'<th></th>'.
'<td>'.$markup.'</td>'.
'<th></th>'.
'<td></td>'.
'</tr>'.
'</table>';
}
}
}

View file

@ -0,0 +1,12 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'view/base');
phutil_require_source('DifferentialInlineCommentView.php');

View file

@ -811,15 +811,17 @@ abstract class LiskDAO {
$this->willWriteData($data); $this->willWriteData($data);
$columns = array_keys($data);
foreach ($columns as $k => $property) {
$columns[$k] = $property;
}
$conn = $this->getConnection('w'); $conn = $this->getConnection('w');
$columns = array_keys($data);
foreach ($data as $key => $value) {
$data[$key] = qsprintf($conn, '%ns', $value);
}
$data = implode(', ', $data);
$conn->query( $conn->query(
'%Q INTO %T (%LC) VALUES (%Ls)', '%Q INTO %T (%LC) VALUES (%Q)',
$mode, $mode,
$this->getTableName(), $this->getTableName(),
$columns, $columns,

View file

@ -22,6 +22,13 @@ class AphrontDialogView extends AphrontView {
private $submitButton; private $submitButton;
private $cancelURI; private $cancelURI;
private $submitURI; private $submitURI;
private $user;
private $hidden = array();
public function setUser(PhabricatorUser $user) {
$this->user = $user;
return $this;
}
public function setSubmitURI($uri) { public function setSubmitURI($uri) {
$this->submitURI = $uri; $this->submitURI = $uri;
@ -47,6 +54,11 @@ class AphrontDialogView extends AphrontView {
return $this; return $this;
} }
public function addHiddenInput($key, $value) {
$this->hidden[$key] = $value;
return $this;
}
final public function render() { final public function render() {
require_celerity_resource('aphront-dialog-view-css'); require_celerity_resource('aphront-dialog-view-css');
@ -59,15 +71,35 @@ class AphrontDialogView extends AphrontView {
} }
if ($this->cancelURI) { if ($this->cancelURI) {
$buttons[] = phutil_render_tag( $buttons[] = javelin_render_tag(
'a', 'a',
array( array(
'href' => $this->cancelURI, 'href' => $this->cancelURI,
'class' => 'button grey', 'class' => 'button grey',
'name' => '__cancel__',
'sigil' => 'jx-workflow-button',
), ),
'Cancel'); 'Cancel');
} }
if (!$this->user) {
throw new Exception(
"You must call setUser() when rendering an AphrontDialogView.");
}
$csrf = $this->user->getCSRFToken();
$hidden_inputs = array();
foreach ($this->hidden as $key => $value) {
$hidden_inputs[] = phutil_render_tag(
'input',
array(
'type' => 'hidden',
'name' => $key,
'value' => $value,
));
}
$hidden_inputs = implode("\n", $hidden_inputs);
return javelin_render_tag( return javelin_render_tag(
'form', 'form',
array( array(
@ -77,6 +109,8 @@ class AphrontDialogView extends AphrontView {
'sigil' => 'jx-dialog', 'sigil' => 'jx-dialog',
), ),
'<input type="hidden" name="__form__" value="1" />'. '<input type="hidden" name="__form__" value="1" />'.
'<input type="hidden" name="__csrf__" value="'.$csrf.'" />'.
$hidden_inputs.
'<div class="aphront-dialog-head">'. '<div class="aphront-dialog-head">'.
phutil_escape_html($this->title). phutil_escape_html($this->title).
'</div>'. '</div>'.

View file

@ -130,3 +130,37 @@
left: 0px; left: 0px;
} }
.differential-inline-comment {
background: #f9f9f1;
border: 1px solid #aaaa88;
font-family: Verdana;
font-size: 11px;
margin: 4px 0px;
max-width: 81ch;
padding: 8px 10px;
width: 100%;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
.differential-inline-comment-head {
font-weight: bold;
color: #333333;
border-bottom: 1px solid #ccccaa;
padding-bottom: 6px;
margin-bottom: 4px;
}
.differential-inline-comment-links,
.differential-inline-comment-line {
font-weight: normal;
font-style: italic;
color: #666666;
float: right;
white-space: nowrap;
}
.differential-inline-comment-edit {
padding-left: 8px;
font-style: normal;
}

View file

@ -53,10 +53,15 @@ JX.behavior('differential-edit-inline-comments', function(config) {
finishSelect(); finishSelect();
} }
function isNewFile(node) { function isOnRight(node) {
return node.parentNode.firstChild != node; return node.parentNode.firstChild != node;
} }
function isNewFile(node) {
var data = JX.Stratcom.getData(root);
return isOnRight(node) || (data.left != data.right);
}
function getRowNumber(th_node) { function getRowNumber(th_node) {
try { try {
return parseInt(th_node.id.match(/^C\d+[ON]L(\d+)$/)[1], 10); return parseInt(th_node.id.match(/^C\d+[ON]L(\d+)$/)[1], 10);
@ -81,10 +86,10 @@ JX.behavior('differential-edit-inline-comments', function(config) {
origin = target = e.getTarget(); origin = target = e.getTarget();
var data = e.getNodeData('differential-changeset'); var data = e.getNodeData('differential-changeset');
if (isNewFile(target)) { if (isOnRight(target)) {
changeset = data.oid; changeset = data.left;
} else { } else {
changeset = data.nid; changeset = data.right;
} }
updateReticle(); updateReticle();
@ -99,7 +104,7 @@ JX.behavior('differential-edit-inline-comments', function(config) {
if (!selecting || if (!selecting ||
workflow || workflow ||
(getRowNumber(e.getTarget()) === undefined) || (getRowNumber(e.getTarget()) === undefined) ||
(isNewFile(e.getTarget()) != isNewFile(origin)) || (isOnRight(e.getTarget()) != isOnRight(origin)) ||
(e.getNode('differential-changeset') !== root)) { (e.getNode('differential-changeset') !== root)) {
return; return;
} }
@ -136,7 +141,8 @@ JX.behavior('differential-edit-inline-comments', function(config) {
changeset: changeset, changeset: changeset,
number: o, number: o,
length: len, length: len,
is_new: isNewFile(target) ? 1 : 0 is_new: isNewFile(target) ? 1 : 0,
on_right: isOnRight(target) ? 1 : 0
}; };
workflow = true; workflow = true;
@ -155,9 +161,7 @@ JX.behavior('differential-edit-inline-comments', function(config) {
} }
drawInlineComment(insert.parentNode, target, r); drawInlineComment(insert.parentNode, target, r);
finishSelect(); finishSelect();
JX.Stratcom.invoke('inline-comment-update', JX.Stratcom.invoke('differential-inline-comment-update');
null,
{id : r.inlineCommentID});
}) })
.setCloseHandler(finishSelect); .setCloseHandler(finishSelect);
@ -175,7 +179,7 @@ JX.behavior('differential-edit-inline-comments', function(config) {
JX.Stratcom.listen( JX.Stratcom.listen(
['mouseover', 'mouseout'], ['mouseover', 'mouseout'],
'inline-comment', 'differential-inline-comment',
function(e) { function(e) {
if (selecting || workflow) { if (selecting || workflow) {
return; return;
@ -184,21 +188,21 @@ JX.behavior('differential-edit-inline-comments', function(config) {
if (e.getType() == 'mouseout') { if (e.getType() == 'mouseout') {
hideReticle(); hideReticle();
} else { } else {
var data = e.getNodeData('inline-comment');
var change = e.getNodeData('differential-changeset');
root = e.getNode('differential-changeset'); root = e.getNode('differential-changeset');
var prefix = 'C' + change; var data = e.getNodeData('differential-inline-comment');
var change = e.getNodeData('differential-changeset');
if (data.is_new) { var prefix;
prefix += 'NL'; if (data.on_right) {
prefix = 'C' + (change.left) + 'NL';
} else { } else {
prefix += 'OL'; prefix = 'C' + (change.right) + 'OL';
} }
origin = JX.$(prefix + data.number); origin = JX.$(prefix + data.number);
target = JX.$(prefix + (data.number + data.length)); target = JX.$(prefix + (parseInt(data.number, 10) +
parseInt(data.length, 10)));
updateReticle(); updateReticle();
} }
@ -206,16 +210,18 @@ JX.behavior('differential-edit-inline-comments', function(config) {
JX.Stratcom.listen( JX.Stratcom.listen(
'click', 'click',
[['inline-comment', 'delete'], [['differential-inline-comment', 'delete'],
['inline-comment', 'edit']], ['differential-inline-comment', 'edit']],
function(e) { function(e) {
var data = { var data = {
op: e.getNode('edit') ? 'edit' : 'delete', op: e.getNode('edit') ? 'edit' : 'delete',
id: e.getNodeData('inline-comment').id id: e.getNodeData('differential-inline-comment').id
}; };
new JX.Workflow(config.uri, data) new JX.Workflow(config.uri, data)
.setHandler(function(r) { .setHandler(function(r) {
var base_row = e.getNode('inline-comment').parentNode.parentNode; var base_row = e.getNode('differential-inline-comment')
.parentNode
.parentNode;
if (data.op == 'edit' && r.markup) { if (data.op == 'edit' && r.markup) {
drawInlineComment(base_row.parentNode, base_row, r); drawInlineComment(base_row.parentNode, base_row, r);
} }

View file

@ -2684,17 +2684,19 @@ JX.install('DOM', {
* @task stratcom * @task stratcom
* @param Node The node to listen for events underneath. * @param Node The node to listen for events underneath.
* @param string|list One or more event types to listen for. * @param string|list One or more event types to listen for.
* @param list? A path to listen on. * @param list? A path to listen on, or a list of paths.
* @param function Callback to invoke when a matching event occurs. * @param function Callback to invoke when a matching event occurs.
* @return object A reference to the installed listener. You can later * @return object A reference to the installed listener. You can later
* remove the listener by calling this object's remove() * remove the listener by calling this object's remove()
* method. * method.
*/ */
listen : function(node, type, path, callback) { listen : function(node, type, path, callback) {
return JX.Stratcom.listen( var id = ['id:' + JX.DOM.uniqID(node)];
type, path = JX.$AX(path || []);
['id:'+JX.DOM.uniqID(node)].concat(JX.$AX(path || [])), for (var ii = 0; ii < path.length; ii++) {
callback); path[ii] = id.concat(JX.$AX(path[ii]));
}
return JX.Stratcom.listen(type, path, callback);
}, },
uniqID : function(node) { uniqID : function(node) {

View file

@ -111,6 +111,7 @@ JX.install('Workflow', {
if (JX.Workflow._disabled) { if (JX.Workflow._disabled) {
return; return;
} }
var t = event.getTarget(); var t = event.getTarget();
if (t.name == '__cancel__' || t.name == '__close__') { if (t.name == '__cancel__' || t.name == '__close__') {
JX.Workflow._pop(); JX.Workflow._pop();
@ -152,7 +153,7 @@ JX.install('Workflow', {
JX.DOM.listen( JX.DOM.listen(
this._root, this._root,
'click', 'click',
'tag:button', [['jx-workflow-button'], ['tag:button']],
JX.Workflow._onbutton); JX.Workflow._onbutton);
document.body.appendChild(this._root); document.body.appendChild(this._root);
var d = JX.$V.getDim(this._root); var d = JX.$V.getDim(this._root);