Page MenuHomePhabricator

D14878.diff
No OneTemporary

D14878.diff

diff --git a/resources/celerity/map.php b/resources/celerity/map.php
--- a/resources/celerity/map.php
+++ b/resources/celerity/map.php
@@ -8,7 +8,7 @@
return array(
'names' => array(
'core.pkg.css' => 'a419cf4b',
- 'core.pkg.js' => 'cf262309',
+ 'core.pkg.js' => 'b826f522',
'darkconsole.pkg.js' => 'e7393ebb',
'differential.pkg.css' => '2de124c9',
'differential.pkg.js' => '64e69521',
@@ -452,7 +452,7 @@
'rsrc/js/core/DragAndDropFileUpload.js' => 'ad10aeac',
'rsrc/js/core/DraggableList.js' => 'a16ec1c6',
'rsrc/js/core/FileUpload.js' => '477359c8',
- 'rsrc/js/core/Hovercard.js' => '14ac66f5',
+ 'rsrc/js/core/Hovercard.js' => '6914d0dd',
'rsrc/js/core/KeyboardShortcut.js' => '1ae869f2',
'rsrc/js/core/KeyboardShortcutManager.js' => 'c1700f6f',
'rsrc/js/core/MultirowRowManager.js' => 'b5d57730',
@@ -747,7 +747,7 @@
'phabricator-file-upload' => '477359c8',
'phabricator-filetree-view-css' => 'fccf9f82',
'phabricator-flag-css' => '5337623f',
- 'phabricator-hovercard' => '14ac66f5',
+ 'phabricator-hovercard' => '6914d0dd',
'phabricator-hovercard-view-css' => '1239cd52',
'phabricator-keyboard-shortcut' => '1ae869f2',
'phabricator-keyboard-shortcut-manager' => 'c1700f6f',
@@ -935,13 +935,6 @@
'javelin-dom',
'javelin-history',
),
- '14ac66f5' => array(
- 'javelin-install',
- 'javelin-dom',
- 'javelin-vector',
- 'javelin-request',
- 'javelin-uri',
- ),
'1ad0a787' => array(
'javelin-install',
'javelin-reactor',
@@ -1311,6 +1304,13 @@
'6882e80a' => array(
'javelin-dom',
),
+ '6914d0dd' => array(
+ 'javelin-install',
+ 'javelin-dom',
+ 'javelin-vector',
+ 'javelin-request',
+ 'javelin-uri',
+ ),
'69adf288' => array(
'javelin-install',
),
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -262,7 +262,6 @@
'ConpherenceEditor' => 'applications/conpherence/editor/ConpherenceEditor.php',
'ConpherenceFormDragAndDropUploadControl' => 'applications/conpherence/view/ConpherenceFormDragAndDropUploadControl.php',
'ConpherenceFulltextQuery' => 'applications/conpherence/query/ConpherenceFulltextQuery.php',
- 'ConpherenceHovercardEventListener' => 'applications/conpherence/events/ConpherenceHovercardEventListener.php',
'ConpherenceImageData' => 'applications/conpherence/constants/ConpherenceImageData.php',
'ConpherenceIndex' => 'applications/conpherence/storage/ConpherenceIndex.php',
'ConpherenceLayoutView' => 'applications/conpherence/view/ConpherenceLayoutView.php',
@@ -420,7 +419,7 @@
'DifferentialHostField' => 'applications/differential/customfield/DifferentialHostField.php',
'DifferentialHostedGitLandingStrategy' => 'applications/differential/landing/DifferentialHostedGitLandingStrategy.php',
'DifferentialHostedMercurialLandingStrategy' => 'applications/differential/landing/DifferentialHostedMercurialLandingStrategy.php',
- 'DifferentialHovercardEventListener' => 'applications/differential/event/DifferentialHovercardEventListener.php',
+ 'DifferentialHovercardEngineExtension' => 'applications/differential/engineextension/DifferentialHovercardEngineExtension.php',
'DifferentialHunk' => 'applications/differential/storage/DifferentialHunk.php',
'DifferentialHunkParser' => 'applications/differential/parser/DifferentialHunkParser.php',
'DifferentialHunkParserTestCase' => 'applications/differential/parser/__tests__/DifferentialHunkParserTestCase.php',
@@ -620,7 +619,7 @@
'DiffusionHistoryController' => 'applications/diffusion/controller/DiffusionHistoryController.php',
'DiffusionHistoryQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionHistoryQueryConduitAPIMethod.php',
'DiffusionHistoryTableView' => 'applications/diffusion/view/DiffusionHistoryTableView.php',
- 'DiffusionHovercardEventListener' => 'applications/diffusion/events/DiffusionHovercardEventListener.php',
+ 'DiffusionHovercardEngineExtension' => 'applications/diffusion/engineextension/DiffusionHovercardEngineExtension.php',
'DiffusionInlineCommentController' => 'applications/diffusion/controller/DiffusionInlineCommentController.php',
'DiffusionInlineCommentPreviewController' => 'applications/diffusion/controller/DiffusionInlineCommentPreviewController.php',
'DiffusionLastModifiedController' => 'applications/diffusion/controller/DiffusionLastModifiedController.php',
@@ -1292,7 +1291,7 @@
'ManiphestExcelFormatTestCase' => 'applications/maniphest/export/__tests__/ManiphestExcelFormatTestCase.php',
'ManiphestExportController' => 'applications/maniphest/controller/ManiphestExportController.php',
'ManiphestGetTaskTransactionsConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestGetTaskTransactionsConduitAPIMethod.php',
- 'ManiphestHovercardEventListener' => 'applications/maniphest/event/ManiphestHovercardEventListener.php',
+ 'ManiphestHovercardEngineExtension' => 'applications/maniphest/engineextension/ManiphestHovercardEngineExtension.php',
'ManiphestInfoConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestInfoConduitAPIMethod.php',
'ManiphestNameIndex' => 'applications/maniphest/storage/ManiphestNameIndex.php',
'ManiphestPriorityConfigOptionType' => 'applications/maniphest/config/ManiphestPriorityConfigOptionType.php',
@@ -2370,6 +2369,8 @@
'PhabricatorHomeMainController' => 'applications/home/controller/PhabricatorHomeMainController.php',
'PhabricatorHomePreferencesSettingsPanel' => 'applications/settings/panel/PhabricatorHomePreferencesSettingsPanel.php',
'PhabricatorHomeQuickCreateController' => 'applications/home/controller/PhabricatorHomeQuickCreateController.php',
+ 'PhabricatorHovercardEngineExtension' => 'applications/search/engineextension/PhabricatorHovercardEngineExtension.php',
+ 'PhabricatorHovercardEngineExtensionModule' => 'applications/search/engineextension/PhabricatorHovercardEngineExtensionModule.php',
'PhabricatorHovercardUIExample' => 'applications/uiexample/examples/PhabricatorHovercardUIExample.php',
'PhabricatorHovercardView' => 'view/widget/hovercard/PhabricatorHovercardView.php',
'PhabricatorHunksManagementMigrateWorkflow' => 'applications/differential/management/PhabricatorHunksManagementMigrateWorkflow.php',
@@ -2711,7 +2712,7 @@
'PhabricatorPeopleDisableController' => 'applications/people/controller/PhabricatorPeopleDisableController.php',
'PhabricatorPeopleEmpowerController' => 'applications/people/controller/PhabricatorPeopleEmpowerController.php',
'PhabricatorPeopleExternalPHIDType' => 'applications/people/phid/PhabricatorPeopleExternalPHIDType.php',
- 'PhabricatorPeopleHovercardEventListener' => 'applications/people/event/PhabricatorPeopleHovercardEventListener.php',
+ 'PhabricatorPeopleHovercardEngineExtension' => 'applications/people/engineextension/PhabricatorPeopleHovercardEngineExtension.php',
'PhabricatorPeopleInviteController' => 'applications/people/controller/PhabricatorPeopleInviteController.php',
'PhabricatorPeopleInviteListController' => 'applications/people/controller/PhabricatorPeopleInviteListController.php',
'PhabricatorPeopleInviteSendController' => 'applications/people/controller/PhabricatorPeopleInviteSendController.php',
@@ -4172,7 +4173,6 @@
'ConpherenceEditor' => 'PhabricatorApplicationTransactionEditor',
'ConpherenceFormDragAndDropUploadControl' => 'AphrontFormControl',
'ConpherenceFulltextQuery' => 'PhabricatorOffsetPagedQuery',
- 'ConpherenceHovercardEventListener' => 'PhabricatorEventListener',
'ConpherenceImageData' => 'ConpherenceConstants',
'ConpherenceIndex' => 'ConpherenceDAO',
'ConpherenceLayoutView' => 'AphrontView',
@@ -4347,7 +4347,7 @@
'DifferentialHostField' => 'DifferentialCustomField',
'DifferentialHostedGitLandingStrategy' => 'DifferentialLandingStrategy',
'DifferentialHostedMercurialLandingStrategy' => 'DifferentialLandingStrategy',
- 'DifferentialHovercardEventListener' => 'PhabricatorEventListener',
+ 'DifferentialHovercardEngineExtension' => 'PhabricatorHovercardEngineExtension',
'DifferentialHunk' => array(
'DifferentialDAO',
'PhabricatorPolicyInterface',
@@ -4568,7 +4568,7 @@
'DiffusionHistoryController' => 'DiffusionController',
'DiffusionHistoryQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
'DiffusionHistoryTableView' => 'DiffusionView',
- 'DiffusionHovercardEventListener' => 'PhabricatorEventListener',
+ 'DiffusionHovercardEngineExtension' => 'PhabricatorHovercardEngineExtension',
'DiffusionInlineCommentController' => 'PhabricatorInlineCommentController',
'DiffusionInlineCommentPreviewController' => 'PhabricatorInlineCommentPreviewController',
'DiffusionLastModifiedController' => 'DiffusionController',
@@ -5361,7 +5361,7 @@
'ManiphestExcelFormatTestCase' => 'PhabricatorTestCase',
'ManiphestExportController' => 'ManiphestController',
'ManiphestGetTaskTransactionsConduitAPIMethod' => 'ManiphestConduitAPIMethod',
- 'ManiphestHovercardEventListener' => 'PhabricatorEventListener',
+ 'ManiphestHovercardEngineExtension' => 'PhabricatorHovercardEngineExtension',
'ManiphestInfoConduitAPIMethod' => 'ManiphestConduitAPIMethod',
'ManiphestNameIndex' => 'ManiphestDAO',
'ManiphestPriorityConfigOptionType' => 'PhabricatorConfigJSONOptionType',
@@ -6624,6 +6624,8 @@
'PhabricatorHomeMainController' => 'PhabricatorHomeController',
'PhabricatorHomePreferencesSettingsPanel' => 'PhabricatorSettingsPanel',
'PhabricatorHomeQuickCreateController' => 'PhabricatorHomeController',
+ 'PhabricatorHovercardEngineExtension' => 'Phobject',
+ 'PhabricatorHovercardEngineExtensionModule' => 'PhabricatorConfigModule',
'PhabricatorHovercardUIExample' => 'PhabricatorUIExample',
'PhabricatorHovercardView' => 'AphrontView',
'PhabricatorHunksManagementMigrateWorkflow' => 'PhabricatorHunksManagementWorkflow',
@@ -7010,7 +7012,7 @@
'PhabricatorPeopleDisableController' => 'PhabricatorPeopleController',
'PhabricatorPeopleEmpowerController' => 'PhabricatorPeopleController',
'PhabricatorPeopleExternalPHIDType' => 'PhabricatorPHIDType',
- 'PhabricatorPeopleHovercardEventListener' => 'PhabricatorEventListener',
+ 'PhabricatorPeopleHovercardEngineExtension' => 'PhabricatorHovercardEngineExtension',
'PhabricatorPeopleInviteController' => 'PhabricatorPeopleController',
'PhabricatorPeopleInviteListController' => 'PhabricatorPeopleInviteController',
'PhabricatorPeopleInviteSendController' => 'PhabricatorPeopleInviteController',
diff --git a/src/applications/conpherence/application/PhabricatorConpherenceApplication.php b/src/applications/conpherence/application/PhabricatorConpherenceApplication.php
--- a/src/applications/conpherence/application/PhabricatorConpherenceApplication.php
+++ b/src/applications/conpherence/application/PhabricatorConpherenceApplication.php
@@ -28,12 +28,6 @@
);
}
- public function getEventListeners() {
- return array(
- new ConpherenceHovercardEventListener(),
- );
- }
-
public function getRoutes() {
return array(
'/Z(?P<id>[1-9]\d*)' => 'ConpherenceViewController',
diff --git a/src/applications/conpherence/events/ConpherenceHovercardEventListener.php b/src/applications/conpherence/events/ConpherenceHovercardEventListener.php
deleted file mode 100644
--- a/src/applications/conpherence/events/ConpherenceHovercardEventListener.php
+++ /dev/null
@@ -1,41 +0,0 @@
-<?php
-
-/**
- * This event listener is tasked with probably one of the most important
- * missions in this world: Adding a Conpherence button to a hovercard.
- *
- * Handle with care when modifying!
- *
- * @task event
- */
-final class ConpherenceHovercardEventListener extends PhabricatorEventListener {
-
- public function register() {
- $this->listen(PhabricatorEventType::TYPE_UI_DIDRENDERHOVERCARD);
- }
-
- public function handleEvent(PhutilEvent $event) {
- switch ($event->getType()) {
- case PhabricatorEventType::TYPE_UI_DIDRENDERHOVERCARD:
- $this->handleHovercardEvent($event);
- break;
- }
- }
-
- private function handleHovercardEvent($event) {
- $hovercard = $event->getValue('hovercard');
- $user = $event->getValue('object');
-
- if (!($user instanceof PhabricatorUser)) {
- return;
- }
-
- $conpherence_uri = id(new PhutilURI('/conpherence/new/'))
- ->setQueryParam('participant', $user->getPHID());
- $name = pht('Send a Message');
- $hovercard->addAction($name, $conpherence_uri, true);
-
- $event->setValue('hovercard', $hovercard);
- }
-
-}
diff --git a/src/applications/differential/application/PhabricatorDifferentialApplication.php b/src/applications/differential/application/PhabricatorDifferentialApplication.php
--- a/src/applications/differential/application/PhabricatorDifferentialApplication.php
+++ b/src/applications/differential/application/PhabricatorDifferentialApplication.php
@@ -44,7 +44,6 @@
public function getEventListeners() {
return array(
new DifferentialActionMenuEventListener(),
- new DifferentialHovercardEventListener(),
new DifferentialLandingActionMenuEventListener(),
);
}
diff --git a/src/applications/differential/engineextension/DifferentialHovercardEngineExtension.php b/src/applications/differential/engineextension/DifferentialHovercardEngineExtension.php
new file mode 100644
--- /dev/null
+++ b/src/applications/differential/engineextension/DifferentialHovercardEngineExtension.php
@@ -0,0 +1,77 @@
+<?php
+
+final class DifferentialHovercardEngineExtension
+ extends PhabricatorHovercardEngineExtension {
+
+ const EXTENSIONKEY = 'differential';
+
+ public function isExtensionEnabled() {
+ return PhabricatorApplication::isClassInstalled(
+ 'PhabricatorDifferentialApplication');
+ }
+
+ public function getExtensionName() {
+ return pht('Differential Revisions');
+ }
+
+ public function canRenderObjectHovercard($object) {
+ return ($object instanceof DifferentialRevision);
+ }
+
+ public function willRenderHovercards(array $objects) {
+ $viewer = $this->getViewer();
+ $phids = mpull($objects, 'getPHID');
+
+ $revisions = id(new DifferentialRevisionQuery())
+ ->setViewer($viewer)
+ ->withPHIDs($phids)
+ ->needReviewerStatus(true)
+ ->execute();
+ $revisions = mpull($revisions, null, 'getPHID');
+
+ return array(
+ 'revisions' => $revisions,
+ );
+ }
+
+ public function renderHovercard(
+ PhabricatorHovercardView $hovercard,
+ PhabricatorObjectHandle $handle,
+ $object,
+ $data) {
+
+ $viewer = $this->getViewer();
+
+ $revision = idx($data['revisions'], $object->getPHID());
+ if (!$revision) {
+ return;
+ }
+
+ $hovercard->setTitle('D'.$revision->getID());
+ $hovercard->setDetail($revision->getTitle());
+
+ $hovercard->addField(
+ pht('Author'),
+ $viewer->renderHandle($revision->getAuthorPHID()));
+
+ $reviewer_phids = $revision->getReviewerStatus();
+ $reviewer_phids = mpull($reviewer_phids, 'getReviewerPHID');
+
+ $hovercard->addField(
+ pht('Reviewers'),
+ $viewer->renderHandleList($reviewer_phids)->setAsInline(true));
+
+ $summary = $revision->getSummary();
+ if (strlen($summary)) {
+ $summary = id(new PhutilUTF8StringTruncator())
+ ->setMaximumGlyphs(120)
+ ->truncateString($summary);
+
+ $hovercard->addField(pht('Summary'), $summary);
+ }
+
+ $tag = DifferentialRevisionDetailView::renderTagForRevision($revision);
+ $hovercard->addTag($tag);
+ }
+
+}
diff --git a/src/applications/differential/event/DifferentialHovercardEventListener.php b/src/applications/differential/event/DifferentialHovercardEventListener.php
deleted file mode 100644
--- a/src/applications/differential/event/DifferentialHovercardEventListener.php
+++ /dev/null
@@ -1,71 +0,0 @@
-<?php
-
-final class DifferentialHovercardEventListener
- extends PhabricatorEventListener {
-
- public function register() {
- $this->listen(PhabricatorEventType::TYPE_UI_DIDRENDERHOVERCARD);
- }
-
- public function handleEvent(PhutilEvent $event) {
- switch ($event->getType()) {
- case PhabricatorEventType::TYPE_UI_DIDRENDERHOVERCARD:
- $this->handleHovercardEvent($event);
- break;
- }
- }
-
- private function handleHovercardEvent($event) {
- $viewer = $event->getUser();
- $hovercard = $event->getValue('hovercard');
- $object_handle = $event->getValue('handle');
- $phid = $object_handle->getPHID();
- $rev = $event->getValue('object');
-
- if (!($rev instanceof DifferentialRevision)) {
- return;
- }
-
- $rev->loadRelationships();
- $reviewer_phids = $rev->getReviewers();
- $e_task = DifferentialRevisionHasTaskEdgeType::EDGECONST;
- $edge_query = id(new PhabricatorEdgeQuery())
- ->withSourcePHIDs(array($phid))
- ->withEdgeTypes(
- array(
- $e_task,
- ));
- $edge_query->execute();
- $tasks = $edge_query->getDestinationPHIDs();
-
- $hovercard->setTitle('D'.$rev->getID());
- $hovercard->setDetail($rev->getTitle());
-
- $hovercard->addField(
- pht('Author'),
- $viewer->renderHandle($rev->getAuthorPHID()));
-
- $hovercard->addField(
- pht('Reviewers'),
- $viewer->renderHandleList($reviewer_phids)->setAsInline(true));
-
- if ($tasks) {
- $hovercard->addField(
- pht('Tasks'),
- $viewer->renderHandleList($tasks)->setAsInline(true));
- }
-
- if ($rev->getSummary()) {
- $hovercard->addField(pht('Summary'),
- id(new PhutilUTF8StringTruncator())
- ->setMaximumGlyphs(120)
- ->truncateString($rev->getSummary()));
- }
-
- $hovercard->addTag(
- DifferentialRevisionDetailView::renderTagForRevision($rev));
-
- $event->setValue('hovercard', $hovercard);
- }
-
-}
diff --git a/src/applications/diffusion/application/PhabricatorDiffusionApplication.php b/src/applications/diffusion/application/PhabricatorDiffusionApplication.php
--- a/src/applications/diffusion/application/PhabricatorDiffusionApplication.php
+++ b/src/applications/diffusion/application/PhabricatorDiffusionApplication.php
@@ -37,12 +37,6 @@
);
}
- public function getEventListeners() {
- return array(
- new DiffusionHovercardEventListener(),
- );
- }
-
public function getRemarkupRules() {
return array(
new DiffusionCommitRemarkupRule(),
diff --git a/src/applications/diffusion/engineextension/DiffusionHovercardEngineExtension.php b/src/applications/diffusion/engineextension/DiffusionHovercardEngineExtension.php
new file mode 100644
--- /dev/null
+++ b/src/applications/diffusion/engineextension/DiffusionHovercardEngineExtension.php
@@ -0,0 +1,53 @@
+<?php
+
+final class DiffusionHovercardEngineExtension
+ extends PhabricatorHovercardEngineExtension {
+
+ const EXTENSIONKEY = 'diffusion';
+
+ public function isExtensionEnabled() {
+ return PhabricatorApplication::isClassInstalled(
+ 'PhabricatorDiffusionApplication');
+ }
+
+ public function getExtensionName() {
+ return pht('Diffusion Commits');
+ }
+
+ public function canRenderObjectHovercard($object) {
+ return ($object instanceof PhabricatorRepositoryCommit);
+ }
+
+ public function renderHovercard(
+ PhabricatorHovercardView $hovercard,
+ PhabricatorObjectHandle $handle,
+ $commit,
+ $data) {
+
+ $viewer = $this->getViewer();
+
+ $author_phid = $commit->getAuthorPHID();
+ if ($author_phid) {
+ $author = $viewer->loadHandle($author)->renderLink();
+ } else {
+ $commit_data = $commit->loadCommitData();
+ $author = phutil_tag('em', array(), $commit_data->getAuthorName());
+ }
+
+ $hovercard->setTitle($handle->getName());
+ $hovercard->setDetail($commit->getSummary());
+
+ $hovercard->addField(pht('Author'), $author);
+ $hovercard->addField(pht('Date'),
+ phabricator_date($commit->getEpoch(), $viewer));
+
+ if ($commit->getAuditStatus() !=
+ PhabricatorAuditCommitStatusConstants::NONE) {
+
+ $hovercard->addField(pht('Audit Status'),
+ PhabricatorAuditCommitStatusConstants::getStatusName(
+ $commit->getAuditStatus()));
+ }
+ }
+
+}
diff --git a/src/applications/diffusion/events/DiffusionHovercardEventListener.php b/src/applications/diffusion/events/DiffusionHovercardEventListener.php
deleted file mode 100644
--- a/src/applications/diffusion/events/DiffusionHovercardEventListener.php
+++ /dev/null
@@ -1,75 +0,0 @@
-<?php
-
-final class DiffusionHovercardEventListener extends PhabricatorEventListener {
-
- public function register() {
- $this->listen(PhabricatorEventType::TYPE_UI_DIDRENDERHOVERCARD);
- }
-
- public function handleEvent(PhutilEvent $event) {
- switch ($event->getType()) {
- case PhabricatorEventType::TYPE_UI_DIDRENDERHOVERCARD:
- $this->handleHovercardEvent($event);
- break;
- }
- }
-
- private function handleHovercardEvent($event) {
- $viewer = $event->getUser();
- $hovercard = $event->getValue('hovercard');
- $object_handle = $event->getValue('handle');
- $commit = $event->getValue('object');
-
- if (!($commit instanceof PhabricatorRepositoryCommit)) {
- return;
- }
-
- $commit_data = $commit->loadCommitData();
-
- $revision = PhabricatorEdgeQuery::loadDestinationPHIDs(
- $commit->getPHID(),
- DiffusionCommitHasRevisionEdgeType::EDGECONST);
- $revision = reset($revision);
-
- $author = $commit->getAuthorPHID();
-
- $phids = array_filter(array(
- $revision,
- $author,
- ));
-
- $handles = id(new PhabricatorHandleQuery())
- ->setViewer($viewer)
- ->withPHIDs($phids)
- ->execute();
-
- if ($author) {
- $author = $handles[$author]->renderLink();
- } else {
- $author = phutil_tag('em', array(), $commit_data->getAuthorName());
- }
-
- $hovercard->setTitle($object_handle->getName());
- $hovercard->setDetail($commit->getSummary());
-
- $hovercard->addField(pht('Author'), $author);
- $hovercard->addField(pht('Date'),
- phabricator_date($commit->getEpoch(), $viewer));
-
- if ($commit->getAuditStatus() !=
- PhabricatorAuditCommitStatusConstants::NONE) {
-
- $hovercard->addField(pht('Audit Status'),
- PhabricatorAuditCommitStatusConstants::getStatusName(
- $commit->getAuditStatus()));
- }
-
- if ($revision) {
- $rev_handle = $handles[$revision];
- $hovercard->addField(pht('Revision'), $rev_handle->renderLink());
- }
-
- $event->setValue('hovercard', $hovercard);
- }
-
-}
diff --git a/src/applications/maniphest/application/PhabricatorManiphestApplication.php b/src/applications/maniphest/application/PhabricatorManiphestApplication.php
--- a/src/applications/maniphest/application/PhabricatorManiphestApplication.php
+++ b/src/applications/maniphest/application/PhabricatorManiphestApplication.php
@@ -36,12 +36,6 @@
);
}
- public function getEventListeners() {
- return array(
- new ManiphestHovercardEventListener(),
- );
- }
-
public function getRemarkupRules() {
return array(
new ManiphestRemarkupRule(),
diff --git a/src/applications/maniphest/engineextension/ManiphestHovercardEngineExtension.php b/src/applications/maniphest/engineextension/ManiphestHovercardEngineExtension.php
new file mode 100644
--- /dev/null
+++ b/src/applications/maniphest/engineextension/ManiphestHovercardEngineExtension.php
@@ -0,0 +1,47 @@
+<?php
+
+final class ManiphestHovercardEngineExtension
+ extends PhabricatorHovercardEngineExtension {
+
+ const EXTENSIONKEY = 'maniphest';
+
+ public function isExtensionEnabled() {
+ return PhabricatorApplication::isClassInstalled(
+ 'PhabricatorManiphestApplication');
+ }
+
+ public function getExtensionName() {
+ return pht('Maniphest Tasks');
+ }
+
+ public function canRenderObjectHovercard($object) {
+ return ($object instanceof ManiphestTask);
+ }
+
+ public function renderHovercard(
+ PhabricatorHovercardView $hovercard,
+ PhabricatorObjectHandle $handle,
+ $task,
+ $data) {
+ $viewer = $this->getViewer();
+
+ $hovercard
+ ->setTitle($task->getMonogram())
+ ->setDetail($task->getTitle());
+
+ $owner_phid = $task->getOwnerPHID();
+ if ($owner_phid) {
+ $owner = $viewer->renderHandle($owner_phid);
+ } else {
+ $owner = phutil_tag('em', array(), pht('None'));
+ }
+ $hovercard->addField(pht('Assigned To'), $owner);
+
+ $hovercard->addField(
+ pht('Priority'),
+ ManiphestTaskPriority::getTaskPriorityName($task->getPriority()));
+
+ $hovercard->addTag(ManiphestView::renderTagForTask($task));
+ }
+
+}
diff --git a/src/applications/maniphest/event/ManiphestHovercardEventListener.php b/src/applications/maniphest/event/ManiphestHovercardEventListener.php
deleted file mode 100644
--- a/src/applications/maniphest/event/ManiphestHovercardEventListener.php
+++ /dev/null
@@ -1,93 +0,0 @@
-<?php
-
-final class ManiphestHovercardEventListener extends PhabricatorEventListener {
-
- public function register() {
- $this->listen(PhabricatorEventType::TYPE_UI_DIDRENDERHOVERCARD);
- }
-
- public function handleEvent(PhutilEvent $event) {
- switch ($event->getType()) {
- case PhabricatorEventType::TYPE_UI_DIDRENDERHOVERCARD:
- $this->handleHovercardEvent($event);
- break;
- }
- }
-
- private function handleHovercardEvent(PhutilEvent $event) {
- $viewer = $event->getUser();
- $hovercard = $event->getValue('hovercard');
- $handle = $event->getValue('handle');
- $phid = $handle->getPHID();
- $task = $event->getValue('object');
-
- if (!($task instanceof ManiphestTask)) {
- return;
- }
-
- $e_project = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
- // Fun with "Unbeta Pholio", hua hua
- $e_dep_on = ManiphestTaskDependsOnTaskEdgeType::EDGECONST;
- $e_dep_by = ManiphestTaskDependedOnByTaskEdgeType::EDGECONST;
-
- $edge_query = id(new PhabricatorEdgeQuery())
- ->withSourcePHIDs(array($phid))
- ->withEdgeTypes(
- array(
- $e_project,
- $e_dep_on,
- $e_dep_by,
- ));
- $edges = idx($edge_query->execute(), $phid);
- $edge_phids = $edge_query->getDestinationPHIDs();
-
- $owner_phid = $task->getOwnerPHID();
-
- $hovercard
- ->setTitle(pht('T%d', $task->getID()))
- ->setDetail($task->getTitle());
-
- if ($owner_phid) {
- $owner = $viewer->renderHandle($owner_phid);
- } else {
- $owner = phutil_tag('em', array(), pht('None'));
- }
- $hovercard->addField(pht('Assigned To'), $owner);
- $hovercard->addField(
- pht('Priority'),
- ManiphestTaskPriority::getTaskPriorityName($task->getPriority()));
-
- if ($edge_phids) {
- $edge_types = array(
- $e_project => pht('Projects'),
- $e_dep_by => pht('Blocks'),
- $e_dep_on => pht('Blocked By'),
- );
-
- $max_count = 6;
- foreach ($edge_types as $edge_type => $edge_name) {
- if ($edges[$edge_type]) {
- // TODO: This can be made more sophisticated. We still load all
- // edges into memory. Only load the ones we need.
- $edge_overflow = array();
- if (count($edges[$edge_type]) > $max_count) {
- $edges[$edge_type] = array_slice($edges[$edge_type], 0, 6, true);
- $edge_overflow = ', ...';
- }
-
- $hovercard->addField(
- $edge_name,
- array(
- $viewer->renderHandleList(array_keys($edges[$edge_type])),
- $edge_overflow,
- ));
- }
- }
- }
-
- $hovercard->addTag(ManiphestView::renderTagForTask($task));
-
- $event->setValue('hovercard', $hovercard);
- }
-
-}
diff --git a/src/applications/people/application/PhabricatorPeopleApplication.php b/src/applications/people/application/PhabricatorPeopleApplication.php
--- a/src/applications/people/application/PhabricatorPeopleApplication.php
+++ b/src/applications/people/application/PhabricatorPeopleApplication.php
@@ -34,12 +34,6 @@
return false;
}
- public function getEventListeners() {
- return array(
- new PhabricatorPeopleHovercardEventListener(),
- );
- }
-
public function getRoutes() {
return array(
'/people/' => array(
diff --git a/src/applications/people/event/PhabricatorPeopleHovercardEventListener.php b/src/applications/people/engineextension/PhabricatorPeopleHovercardEngineExtension.php
rename from src/applications/people/event/PhabricatorPeopleHovercardEventListener.php
rename to src/applications/people/engineextension/PhabricatorPeopleHovercardEngineExtension.php
--- a/src/applications/people/event/PhabricatorPeopleHovercardEventListener.php
+++ b/src/applications/people/engineextension/PhabricatorPeopleHovercardEngineExtension.php
@@ -1,45 +1,58 @@
<?php
-final class PhabricatorPeopleHovercardEventListener
- extends PhabricatorEventListener {
+final class PhabricatorPeopleHovercardEngineExtension
+ extends PhabricatorHovercardEngineExtension {
- public function register() {
- $this->listen(PhabricatorEventType::TYPE_UI_DIDRENDERHOVERCARD);
+ const EXTENSIONKEY = 'people';
+
+ public function isExtensionEnabled() {
+ return true;
}
- public function handleEvent(PhutilEvent $event) {
- switch ($event->getType()) {
- case PhabricatorEventType::TYPE_UI_DIDRENDERHOVERCARD:
- $this->handleHovercardEvent($event);
- break;
- }
+ public function getExtensionName() {
+ return pht('User Accounts');
}
- private function handleHovercardEvent($event) {
- $viewer = $event->getUser();
- $hovercard = $event->getValue('hovercard');
- $object_handle = $event->getValue('handle');
- $phid = $object_handle->getPHID();
- $user = $event->getValue('object');
+ public function canRenderObjectHovercard($object) {
+ return ($object instanceof PhabricatorUser);
+ }
- if (!($user instanceof PhabricatorUser)) {
- return;
- }
+ public function willRenderHovercards(array $objects) {
+ $viewer = $this->getViewer();
+ $phids = mpull($objects, 'getPHID');
- // Reload to get availability.
- $user = id(new PhabricatorPeopleQuery())
+ $users = id(new PhabricatorPeopleQuery())
->setViewer($viewer)
- ->withIDs(array($user->getID()))
+ ->withPHIDs($phids)
->needAvailability(true)
->needProfile(true)
->needBadges(true)
- ->executeOne();
+ ->execute();
+ $users = mpull($users, null, 'getPHID');
+
+ return array(
+ 'users' => $users,
+ );
+ }
+
+ public function renderHovercard(
+ PhabricatorHovercardView $hovercard,
+ PhabricatorObjectHandle $handle,
+ $object,
+ $data) {
+ $viewer = $this->getViewer();
+
+ $user = idx($data['users'], $object->getPHID());
+ if (!$user) {
+ return;
+ }
$hovercard->setTitle($user->getUsername());
+
$profile = $user->getUserProfile();
$detail = $user->getRealName();
if ($profile->getTitle()) {
- $detail .= ' - '.$profile->getTitle().'.';
+ $detail .= ' - '.$profile->getTitle();
}
$hovercard->setDetail($detail);
@@ -70,8 +83,6 @@
foreach ($badges as $badge) {
$hovercard->addBadge($badge);
}
-
- $event->setValue('hovercard', $hovercard);
}
private function buildBadges(
@@ -101,5 +112,4 @@
return $items;
}
-
}
diff --git a/src/applications/search/application/PhabricatorSearchApplication.php b/src/applications/search/application/PhabricatorSearchApplication.php
--- a/src/applications/search/application/PhabricatorSearchApplication.php
+++ b/src/applications/search/application/PhabricatorSearchApplication.php
@@ -35,7 +35,7 @@
'select/(?P<type>\w+)/(?:(?P<action>\w+)/)?'
=> 'PhabricatorSearchSelectController',
'index/(?P<phid>[^/]+)/' => 'PhabricatorSearchIndexController',
- 'hovercard/(?P<mode>retrieve|test)/'
+ 'hovercard/'
=> 'PhabricatorSearchHovercardController',
'edit/(?P<queryKey>[^/]+)/' => 'PhabricatorSearchEditController',
'delete/(?P<queryKey>[^/]+)/(?P<engine>[^/]+)/'
diff --git a/src/applications/search/controller/PhabricatorSearchHovercardController.php b/src/applications/search/controller/PhabricatorSearchHovercardController.php
--- a/src/applications/search/controller/PhabricatorSearchHovercardController.php
+++ b/src/applications/search/controller/PhabricatorSearchHovercardController.php
@@ -15,13 +15,43 @@
->setViewer($viewer)
->withPHIDs($phids)
->execute();
+
$objects = id(new PhabricatorObjectQuery())
->setViewer($viewer)
->withPHIDs($phids)
->execute();
+ $objects = mpull($objects, null, 'getPHID');
- $cards = array();
+ $extensions =
+ PhabricatorHovercardEngineExtension::getAllEnabledExtensions();
+
+ $extension_maps = array();
+ foreach ($extensions as $key => $extension) {
+ $extension->setViewer($viewer);
+
+ $extension_phids = array();
+ foreach ($objects as $phid => $object) {
+ if ($extension->canRenderObjectHovercard($object)) {
+ $extension_phids[$phid] = $phid;
+ }
+ }
+
+ $extension_maps[$key] = $extension_phids;
+ }
+
+ $extension_data = array();
+ foreach ($extensions as $key => $extension) {
+ $extension_phids = $extension_maps[$key];
+ if (!$extension_phids) {
+ unset($extensions[$key]);
+ continue;
+ }
+ $extension_data[$key] = $extension->willRenderHovercards(
+ array_select_keys($objects, $extension_phids));
+ }
+
+ $cards = array();
foreach ($phids as $phid) {
$handle = $handles[$phid];
$object = $objects[$phid];
@@ -32,43 +62,39 @@
if ($object) {
$hovercard->setObject($object);
- }
- // Send it to the other side of the world, thanks to PhutilEventEngine
- $event = new PhabricatorEvent(
- PhabricatorEventType::TYPE_UI_DIDRENDERHOVERCARD,
- array(
- 'hovercard' => $hovercard,
- 'handle' => $handle,
- 'object' => $object,
- ));
- $event->setUser($viewer);
- PhutilEventEngine::dispatchEvent($event);
+ foreach ($extension_maps as $key => $extension_phids) {
+ if (isset($extension_phids[$phid])) {
+ $extensions[$key]->renderHovercard(
+ $hovercard,
+ $handle,
+ $object,
+ $extension_data[$key]);
+ }
+ }
+ }
$cards[$phid] = $hovercard;
}
- // Browser-friendly for non-Ajax requests
- if (!$request->isAjax()) {
- foreach ($cards as $key => $hovercard) {
- $cards[$key] = phutil_tag('div',
- array(
- 'class' => 'ml',
- ),
- $hovercard);
- }
-
- return $this->buildApplicationPage(
- $cards,
- array(
- 'device' => false,
- ));
- } else {
+ if ($request->isAjax()) {
return id(new AphrontAjaxResponse())->setContent(
array(
'cards' => $cards,
));
}
+
+ foreach ($cards as $key => $hovercard) {
+ $cards[$key] = phutil_tag('div',
+ array(
+ 'class' => 'ml',
+ ),
+ $hovercard);
+ }
+
+ return $this->newPage()
+ ->appendChild($cards)
+ ->setShowFooter(false);
}
}
diff --git a/src/applications/search/engineextension/PhabricatorHovercardEngineExtension.php b/src/applications/search/engineextension/PhabricatorHovercardEngineExtension.php
new file mode 100644
--- /dev/null
+++ b/src/applications/search/engineextension/PhabricatorHovercardEngineExtension.php
@@ -0,0 +1,60 @@
+<?php
+
+abstract class PhabricatorHovercardEngineExtension extends Phobject {
+
+ private $viewer;
+
+ final public function getExtensionKey() {
+ return $this->getPhobjectClassConstant('EXTENSIONKEY');
+ }
+
+ final public function setViewer($viewer) {
+ $this->viewer = $viewer;
+ return $this;
+ }
+
+ final public function getViewer() {
+ return $this->viewer;
+ }
+
+ abstract public function isExtensionEnabled();
+
+ abstract public function getExtensionName();
+
+ abstract public function canRenderObjectHovercard($object);
+
+ public function getExtensionOrder() {
+ return 5000;
+ }
+
+ public function willRenderHovercards(array $objects) {
+ return null;
+ }
+
+ abstract public function renderHovercard(
+ PhabricatorHovercardView $hovercard,
+ PhabricatorObjectHandle $handle,
+ $object,
+ $data);
+
+ final public static function getAllExtensions() {
+ return id(new PhutilClassMapQuery())
+ ->setAncestorClass(__CLASS__)
+ ->setUniqueMethod('getExtensionKey')
+ ->setSortMethod('getExtensionOrder')
+ ->execute();
+ }
+
+ final public static function getAllEnabledExtensions() {
+ $extensions = self::getAllExtensions();
+
+ foreach ($extensions as $key => $extension) {
+ if (!$extension->isExtensionEnabled()) {
+ unset($extensions[$key]);
+ }
+ }
+
+ return $extensions;
+ }
+
+}
diff --git a/src/applications/search/engineextension/PhabricatorHovercardEngineExtensionModule.php b/src/applications/search/engineextension/PhabricatorHovercardEngineExtensionModule.php
new file mode 100644
--- /dev/null
+++ b/src/applications/search/engineextension/PhabricatorHovercardEngineExtensionModule.php
@@ -0,0 +1,55 @@
+<?php
+
+final class PhabricatorHovercardEngineExtensionModule
+ extends PhabricatorConfigModule {
+
+ public function getModuleKey() {
+ return 'hovercardengine';
+ }
+
+ public function getModuleName() {
+ return pht('Engine: Hovercards');
+ }
+
+ public function renderModuleStatus(AphrontRequest $request) {
+ $viewer = $request->getViewer();
+
+ $extensions = PhabricatorHovercardEngineExtension::getAllExtensions();
+
+ $rows = array();
+ foreach ($extensions as $extension) {
+ $rows[] = array(
+ $extension->getExtensionOrder(),
+ $extension->getExtensionKey(),
+ get_class($extension),
+ $extension->getExtensionName(),
+ $extension->isExtensionEnabled()
+ ? pht('Yes')
+ : pht('No'),
+ );
+ }
+
+ $table = id(new AphrontTableView($rows))
+ ->setHeaders(
+ array(
+ pht('Order'),
+ pht('Key'),
+ pht('Class'),
+ pht('Name'),
+ pht('Enabled'),
+ ))
+ ->setColumnClasses(
+ array(
+ null,
+ null,
+ null,
+ 'wide pri',
+ null,
+ ));
+
+ return id(new PHUIObjectBoxView())
+ ->setHeaderText(pht('HovercardEngine Extensions'))
+ ->setTable($table);
+ }
+
+}
diff --git a/src/infrastructure/events/constant/PhabricatorEventType.php b/src/infrastructure/events/constant/PhabricatorEventType.php
--- a/src/infrastructure/events/constant/PhabricatorEventType.php
+++ b/src/infrastructure/events/constant/PhabricatorEventType.php
@@ -20,8 +20,6 @@
const TYPE_UI_DIDRENDEROBJECTS = 'ui.didRenderObjects';
const TYPE_UI_WILLRENDERPROPERTIES = 'ui.willRenderProperties';
- const TYPE_UI_DIDRENDERHOVERCARD = 'ui.didRenderHovercard';
-
const TYPE_PEOPLE_DIDRENDERMENU = 'people.didRenderMenu';
const TYPE_AUTH_WILLREGISTERUSER = 'auth.willRegisterUser';
const TYPE_AUTH_WILLLOGINUSER = 'auth.willLoginUser';
diff --git a/webroot/rsrc/js/core/Hovercard.js b/webroot/rsrc/js/core/Hovercard.js
--- a/webroot/rsrc/js/core/Hovercard.js
+++ b/webroot/rsrc/js/core/Hovercard.js
@@ -15,7 +15,7 @@
_activeRoot : null,
_visiblePHID : null,
- fetchUrl : '/search/hovercard/retrieve/',
+ fetchUrl : '/search/hovercard/',
/**
* Hovercard storage. {"PHID-XXXX-YYYY":"<...>", ...}

File Metadata

Mime Type
text/plain
Expires
Sun, May 12, 6:33 AM (2 w, 6 d ago)
Storage Engine
amazon-s3
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
phabricator/secure/4k/c5/r7g52wigoqtjwme4
Default Alt Text
D14878.diff (39 KB)

Event Timeline