1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-29 10:12:41 +01:00

Merge branch 'master' into phutil_tag

(Synchronizing.)
This commit is contained in:
epriestley 2013-01-29 11:05:02 -08:00
commit 39221b1d3f
88 changed files with 1195 additions and 576 deletions

View file

@ -839,6 +839,9 @@ return array(
// Should Phabricator show beta applications on the homepage // Should Phabricator show beta applications on the homepage
'phabricator.show-beta-applications' => false, 'phabricator.show-beta-applications' => false,
// Contains a list of uninstalled applications
'phabricator.uninstalled-applications' => array(),
// -- Files ----------------------------------------------------------------- // // -- Files ----------------------------------------------------------------- //
// Lists which uploaded file types may be viewed in the browser. If a file // Lists which uploaded file types may be viewed in the browser. If a file

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 886 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 895 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 385 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 410 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,005 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 965 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 418 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 421 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 306 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 295 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 776 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 923 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -0,0 +1,81 @@
{
"version" : 1,
"sprites" : {
"conpher_calendar_off" : {
"name" : "conpher_calendar_off",
"rule" : ".conpher_calendar_off",
"hash" : "a8228ab90fd90f4c2500d9285179bf26"
},
"conpher_calendar_on" : {
"name" : "conpher_calendar_on",
"rule" : ".conpher_calendar_on, .device-desktop .conpher_calendar_off:hover ",
"hash" : "931243bc3c414782ddb2d1d9607908ba"
},
"conpher_conversation_off" : {
"name" : "conpher_conversation_off",
"rule" : ".conpher_conversation_off",
"hash" : "931abb0377898297a9a603a6d280b977"
},
"conpher_conversation_on" : {
"name" : "conpher_conversation_on",
"rule" : ".conpher_conversation_on, .device-desktop .conpher_conversation_off:hover ",
"hash" : "0b8a39dc5019dac1975b7be2ca0ccbfa"
},
"conpher_files_off" : {
"name" : "conpher_files_off",
"rule" : ".conpher_files_off",
"hash" : "de1aee01b9b47b354e6ac280ae68bae1"
},
"conpher_files_on" : {
"name" : "conpher_files_on",
"rule" : ".conpher_files_on, .device-desktop .conpher_files_off:hover ",
"hash" : "9ccbbd5e86fd4ec87a11aee0c9ec8c60"
},
"conpher_list_off" : {
"name" : "conpher_list_off",
"rule" : ".conpher_list_off",
"hash" : "2611311d0c2aec04416433be74d3a30e"
},
"conpher_list_on" : {
"name" : "conpher_list_on",
"rule" : ".conpher_list_on, .device-desktop .conpher_list_off:hover ",
"hash" : "cee6de0301c84b0d195282642642afa0"
},
"conpher_more_off" : {
"name" : "conpher_more_off",
"rule" : ".conpher_more_off",
"hash" : "3b7099bdde20a13864b48552b11e92c3"
},
"conpher_more_on" : {
"name" : "conpher_more_on",
"rule" : ".conpher_more_on, .device-desktop .conpher_more_off:hover ",
"hash" : "b146f0cff9c2e5f0b57f7ebcfe0704d3"
},
"conpher_people_off" : {
"name" : "conpher_people_off",
"rule" : ".conpher_people_off",
"hash" : "641a6a21aa32a12416e85caf8a22e340"
},
"conpher_people_on" : {
"name" : "conpher_people_on",
"rule" : ".conpher_people_on, .device-desktop .conpher_people_off:hover ",
"hash" : "f13745fd7036564eefb1c0ebc3502a92"
},
"conpher_settings_off" : {
"name" : "conpher_settings_off",
"rule" : ".conpher_settings_off",
"hash" : "aa9ab000d9e33e3c50c2fe70367f30b4"
},
"conpher_settings_on" : {
"name" : "conpher_settings_on",
"rule" : ".conpher_settings_on, .device-desktop .conpher_settings_off:hover ",
"hash" : "a5fe22965997f9559800ca7db5ea32c8"
}
},
"scales" : [
1,
2
],
"header" : "\/**\n * @provides sprite-conpher-css\n * @generated\n *\/\n\n.sprite-conpher {\n background-image: url(\/rsrc\/image\/sprite-conpher.png);\n background-repeat: no-repeat;\n}\n\n@media\nonly screen and (min-device-pixel-ratio: 1.5),\nonly screen and (-webkit-min-device-pixel-ratio: 1.5) {\n .sprite-conpher {\n background-image: url(\/rsrc\/image\/sprite-conpher-X2.png);\n background-size: {X}px {Y}px;\n }\n}\n",
"type" : "standard"
}

View file

@ -30,6 +30,7 @@ $sheets = array(
'icon' => $generator->buildIconSheet(), 'icon' => $generator->buildIconSheet(),
'menu' => $generator->buildMenuSheet(), 'menu' => $generator->buildMenuSheet(),
'apps' => $generator->buildAppsSheet(), 'apps' => $generator->buildAppsSheet(),
'conph' => $generator->buildConpherenceSheet(),
'apps-large' => $generator->buildAppsLargeSheet(), 'apps-large' => $generator->buildAppsLargeSheet(),
// TODO: @chad: should we actually remove this? // TODO: @chad: should we actually remove this?
// 'apps-xlarge' => $generator->buildAppsXLargeSheet(), // 'apps-xlarge' => $generator->buildAppsXLargeSheet(),

View file

@ -483,6 +483,20 @@ celerity_register_resource_map(array(
'disk' => '/rsrc/image/sprite-apps.png', 'disk' => '/rsrc/image/sprite-apps.png',
'type' => 'png', 'type' => 'png',
), ),
'/rsrc/image/sprite-conph-X2.png' =>
array(
'hash' => '8f79b9888577dab95d6019d1b7f2a204',
'uri' => '/res/8f79b988/rsrc/image/sprite-conph-X2.png',
'disk' => '/rsrc/image/sprite-conph-X2.png',
'type' => 'png',
),
'/rsrc/image/sprite-conph.png' =>
array(
'hash' => 'a6329b4baa648b57c00de65f6758cbd2',
'uri' => '/res/a6329b4b/rsrc/image/sprite-conph.png',
'disk' => '/rsrc/image/sprite-conph.png',
'type' => 'png',
),
'/rsrc/image/sprite-gradient.png' => '/rsrc/image/sprite-gradient.png' =>
array( array(
'hash' => '92aebaab67dcc6baf2ea99294368d895', 'hash' => '92aebaab67dcc6baf2ea99294368d895',
@ -677,7 +691,7 @@ celerity_register_resource_map(array(
), ),
'aphront-panel-view-css' => 'aphront-panel-view-css' =>
array( array(
'uri' => '/res/789ff5e5/rsrc/css/aphront/panel-view.css', 'uri' => '/res/3d1420b3/rsrc/css/aphront/panel-view.css',
'type' => 'css', 'type' => 'css',
'requires' => 'requires' =>
array( array(
@ -804,7 +818,7 @@ celerity_register_resource_map(array(
), ),
'differential-inline-comment-editor' => 'differential-inline-comment-editor' =>
array( array(
'uri' => '/res/1bc649b7/rsrc/js/application/differential/DifferentialInlineCommentEditor.js', 'uri' => '/res/e0ad34ac/rsrc/js/application/differential/DifferentialInlineCommentEditor.js',
'type' => 'js', 'type' => 'js',
'requires' => 'requires' =>
array( array(
@ -994,7 +1008,7 @@ celerity_register_resource_map(array(
), ),
'javelin-behavior-aphlict-dropdown' => 'javelin-behavior-aphlict-dropdown' =>
array( array(
'uri' => '/res/f09bc90d/rsrc/js/application/aphlict/behavior-aphlict-dropdown.js', 'uri' => '/res/2418f448/rsrc/js/application/aphlict/behavior-aphlict-dropdown.js',
'type' => 'js', 'type' => 'js',
'requires' => 'requires' =>
array( array(
@ -1064,7 +1078,7 @@ celerity_register_resource_map(array(
), ),
'javelin-behavior-aphront-form-disable-on-submit' => 'javelin-behavior-aphront-form-disable-on-submit' =>
array( array(
'uri' => '/res/70fd43fd/rsrc/js/application/core/behavior-form.js', 'uri' => '/res/b5052cd0/rsrc/js/application/core/behavior-form.js',
'type' => 'js', 'type' => 'js',
'requires' => 'requires' =>
array( array(
@ -1791,7 +1805,7 @@ celerity_register_resource_map(array(
), ),
'javelin-behavior-phabricator-transaction-list' => 'javelin-behavior-phabricator-transaction-list' =>
array( array(
'uri' => '/res/307a71af/rsrc/js/application/transactions/behavior-transaction-list.js', 'uri' => '/res/f1fbb474/rsrc/js/application/transactions/behavior-transaction-list.js',
'type' => 'js', 'type' => 'js',
'requires' => 'requires' =>
array( array(
@ -1829,6 +1843,17 @@ celerity_register_resource_map(array(
), ),
'disk' => '/rsrc/js/application/phame/phame-post-preview.js', 'disk' => '/rsrc/js/application/phame/phame-post-preview.js',
), ),
'javelin-behavior-pholio-mock-view' =>
array(
'uri' => '/res/10fbdca1/rsrc/js/application/pholio/behavior-pholio-mock-view.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
),
'disk' => '/rsrc/js/application/pholio/behavior-pholio-mock-view.js',
),
'javelin-behavior-phriction-document-preview' => 'javelin-behavior-phriction-document-preview' =>
array( array(
'uri' => '/res/f1665ecd/rsrc/js/application/phriction/phriction-document-preview.js', 'uri' => '/res/f1665ecd/rsrc/js/application/phriction/phriction-document-preview.js',
@ -1947,7 +1972,7 @@ celerity_register_resource_map(array(
), ),
'javelin-behavior-workflow' => 'javelin-behavior-workflow' =>
array( array(
'uri' => '/res/2b0e2754/rsrc/js/application/core/behavior-workflow.js', 'uri' => '/res/2c99beaf/rsrc/js/application/core/behavior-workflow.js',
'type' => 'js', 'type' => 'js',
'requires' => 'requires' =>
array( array(
@ -2708,7 +2733,7 @@ celerity_register_resource_map(array(
), ),
'phabricator-main-menu-view' => 'phabricator-main-menu-view' =>
array( array(
'uri' => '/res/38ec42d4/rsrc/css/application/base/main-menu-view.css', 'uri' => '/res/597e394b/rsrc/css/application/base/main-menu-view.css',
'type' => 'css', 'type' => 'css',
'requires' => 'requires' =>
array( array(
@ -2728,7 +2753,7 @@ celerity_register_resource_map(array(
), ),
'phabricator-nav-view-css' => 'phabricator-nav-view-css' =>
array( array(
'uri' => '/res/df20ec17/rsrc/css/aphront/phabricator-nav-view.css', 'uri' => '/res/f3c78a53/rsrc/css/aphront/phabricator-nav-view.css',
'type' => 'css', 'type' => 'css',
'requires' => 'requires' =>
array( array(
@ -2760,7 +2785,7 @@ celerity_register_resource_map(array(
), ),
'phabricator-notification-menu-css' => 'phabricator-notification-menu-css' =>
array( array(
'uri' => '/res/d0d0264c/rsrc/css/application/base/notification-menu.css', 'uri' => '/res/b7cc25af/rsrc/css/application/base/notification-menu.css',
'type' => 'css', 'type' => 'css',
'requires' => 'requires' =>
array( array(
@ -2905,7 +2930,7 @@ celerity_register_resource_map(array(
), ),
'phabricator-side-menu-view-css' => 'phabricator-side-menu-view-css' =>
array( array(
'uri' => '/res/2013e94f/rsrc/css/layout/phabricator-side-menu-view.css', 'uri' => '/res/28a1e092/rsrc/css/layout/phabricator-side-menu-view.css',
'type' => 'css', 'type' => 'css',
'requires' => 'requires' =>
array( array(
@ -2982,7 +3007,7 @@ celerity_register_resource_map(array(
), ),
'phabricator-transaction-view-css' => 'phabricator-transaction-view-css' =>
array( array(
'uri' => '/res/d3599152/rsrc/css/aphront/transaction.css', 'uri' => '/res/4c5c16dc/rsrc/css/aphront/transaction.css',
'type' => 'css', 'type' => 'css',
'requires' => 'requires' =>
array( array(
@ -3160,7 +3185,7 @@ celerity_register_resource_map(array(
), ),
'pholio-css' => 'pholio-css' =>
array( array(
'uri' => '/res/e454c33f/rsrc/css/application/pholio/pholio.css', 'uri' => '/res/f101ad7c/rsrc/css/application/pholio/pholio.css',
'type' => 'css', 'type' => 'css',
'requires' => 'requires' =>
array( array(
@ -3284,6 +3309,15 @@ celerity_register_resource_map(array(
), ),
'disk' => '/rsrc/css/sprite-apps-xlarge.css', 'disk' => '/rsrc/css/sprite-apps-xlarge.css',
), ),
'sprite-conpher-css' =>
array(
'uri' => '/res/f640f0c5/rsrc/css/sprite-conph.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/sprite-conph.css',
),
'sprite-gradient-css' => 'sprite-gradient-css' =>
array( array(
'uri' => '/res/e62e7a0f/rsrc/css/sprite-gradient.css', 'uri' => '/res/e62e7a0f/rsrc/css/sprite-gradient.css',
@ -3341,7 +3375,7 @@ celerity_register_resource_map(array(
), array( ), array(
'packages' => 'packages' =>
array( array(
'023adc14' => '0cb71c48' =>
array( array(
'name' => 'core.pkg.css', 'name' => 'core.pkg.css',
'symbols' => 'symbols' =>
@ -3385,10 +3419,10 @@ celerity_register_resource_map(array(
36 => 'phabricator-object-item-list-view-css', 36 => 'phabricator-object-item-list-view-css',
37 => 'global-drag-and-drop-css', 37 => 'global-drag-and-drop-css',
), ),
'uri' => '/res/pkg/023adc14/core.pkg.css', 'uri' => '/res/pkg/0cb71c48/core.pkg.css',
'type' => 'css', 'type' => 'css',
), ),
'b3c1b6e7' => 'ff199687' =>
array( array(
'name' => 'core.pkg.js', 'name' => 'core.pkg.js',
'symbols' => 'symbols' =>
@ -3427,7 +3461,7 @@ celerity_register_resource_map(array(
31 => 'javelin-behavior-global-drag-and-drop', 31 => 'javelin-behavior-global-drag-and-drop',
32 => 'javelin-behavior-phabricator-home-reveal-tiles', 32 => 'javelin-behavior-phabricator-home-reveal-tiles',
), ),
'uri' => '/res/pkg/b3c1b6e7/core.pkg.js', 'uri' => '/res/pkg/ff199687/core.pkg.js',
'type' => 'js', 'type' => 'js',
), ),
'032118cf' => '032118cf' =>
@ -3464,7 +3498,7 @@ celerity_register_resource_map(array(
'uri' => '/res/pkg/ec01d039/differential.pkg.css', 'uri' => '/res/pkg/ec01d039/differential.pkg.css',
'type' => 'css', 'type' => 'css',
), ),
'310cd201' => '9dae5f20' =>
array( array(
'name' => 'differential.pkg.js', 'name' => 'differential.pkg.js',
'symbols' => 'symbols' =>
@ -3489,7 +3523,7 @@ celerity_register_resource_map(array(
17 => 'javelin-behavior-differential-toggle-files', 17 => 'javelin-behavior-differential-toggle-files',
18 => 'javelin-behavior-differential-user-select', 18 => 'javelin-behavior-differential-user-select',
), ),
'uri' => '/res/pkg/310cd201/differential.pkg.js', 'uri' => '/res/pkg/9dae5f20/differential.pkg.js',
'type' => 'js', 'type' => 'js',
), ),
'c8ce2d88' => 'c8ce2d88' =>
@ -3574,22 +3608,22 @@ celerity_register_resource_map(array(
'reverse' => 'reverse' =>
array( array(
'aphront-attached-file-view-css' => 'e30a3fa8', 'aphront-attached-file-view-css' => 'e30a3fa8',
'aphront-crumbs-view-css' => '023adc14', 'aphront-crumbs-view-css' => '0cb71c48',
'aphront-dialog-view-css' => '023adc14', 'aphront-dialog-view-css' => '0cb71c48',
'aphront-error-view-css' => '023adc14', 'aphront-error-view-css' => '0cb71c48',
'aphront-form-view-css' => '023adc14', 'aphront-form-view-css' => '0cb71c48',
'aphront-headsup-action-list-view-css' => 'ec01d039', 'aphront-headsup-action-list-view-css' => 'ec01d039',
'aphront-headsup-view-css' => '023adc14', 'aphront-headsup-view-css' => '0cb71c48',
'aphront-list-filter-view-css' => '023adc14', 'aphront-list-filter-view-css' => '0cb71c48',
'aphront-pager-view-css' => '023adc14', 'aphront-pager-view-css' => '0cb71c48',
'aphront-panel-view-css' => '023adc14', 'aphront-panel-view-css' => '0cb71c48',
'aphront-table-view-css' => '023adc14', 'aphront-table-view-css' => '0cb71c48',
'aphront-tokenizer-control-css' => '023adc14', 'aphront-tokenizer-control-css' => '0cb71c48',
'aphront-tooltip-css' => '023adc14', 'aphront-tooltip-css' => '0cb71c48',
'aphront-typeahead-control-css' => '023adc14', 'aphront-typeahead-control-css' => '0cb71c48',
'differential-changeset-view-css' => 'ec01d039', 'differential-changeset-view-css' => 'ec01d039',
'differential-core-view-css' => 'ec01d039', 'differential-core-view-css' => 'ec01d039',
'differential-inline-comment-editor' => '310cd201', 'differential-inline-comment-editor' => '9dae5f20',
'differential-local-commits-view-css' => 'ec01d039', 'differential-local-commits-view-css' => 'ec01d039',
'differential-results-table-css' => 'ec01d039', 'differential-results-table-css' => 'ec01d039',
'differential-revision-add-comment-css' => 'ec01d039', 'differential-revision-add-comment-css' => 'ec01d039',
@ -3600,57 +3634,57 @@ celerity_register_resource_map(array(
'differential-table-of-contents-css' => 'ec01d039', 'differential-table-of-contents-css' => 'ec01d039',
'diffusion-commit-view-css' => 'c8ce2d88', 'diffusion-commit-view-css' => 'c8ce2d88',
'diffusion-icons-css' => 'c8ce2d88', 'diffusion-icons-css' => 'c8ce2d88',
'global-drag-and-drop-css' => '023adc14', 'global-drag-and-drop-css' => '0cb71c48',
'inline-comment-summary-css' => 'ec01d039', 'inline-comment-summary-css' => 'ec01d039',
'javelin-aphlict' => 'b3c1b6e7', 'javelin-aphlict' => 'ff199687',
'javelin-behavior' => '1c6f020b', 'javelin-behavior' => '1c6f020b',
'javelin-behavior-aphlict-dropdown' => 'b3c1b6e7', 'javelin-behavior-aphlict-dropdown' => 'ff199687',
'javelin-behavior-aphlict-listen' => 'b3c1b6e7', 'javelin-behavior-aphlict-listen' => 'ff199687',
'javelin-behavior-aphront-basic-tokenizer' => 'b3c1b6e7', 'javelin-behavior-aphront-basic-tokenizer' => 'ff199687',
'javelin-behavior-aphront-drag-and-drop' => '310cd201', 'javelin-behavior-aphront-drag-and-drop' => '9dae5f20',
'javelin-behavior-aphront-drag-and-drop-textarea' => '310cd201', 'javelin-behavior-aphront-drag-and-drop-textarea' => '9dae5f20',
'javelin-behavior-aphront-form-disable-on-submit' => 'b3c1b6e7', 'javelin-behavior-aphront-form-disable-on-submit' => 'ff199687',
'javelin-behavior-audit-preview' => 'f96657b8', 'javelin-behavior-audit-preview' => 'f96657b8',
'javelin-behavior-dark-console' => '032118cf', 'javelin-behavior-dark-console' => '032118cf',
'javelin-behavior-device' => 'b3c1b6e7', 'javelin-behavior-device' => 'ff199687',
'javelin-behavior-differential-accept-with-errors' => '310cd201', 'javelin-behavior-differential-accept-with-errors' => '9dae5f20',
'javelin-behavior-differential-add-reviewers-and-ccs' => '310cd201', 'javelin-behavior-differential-add-reviewers-and-ccs' => '9dae5f20',
'javelin-behavior-differential-comment-jump' => '310cd201', 'javelin-behavior-differential-comment-jump' => '9dae5f20',
'javelin-behavior-differential-diff-radios' => '310cd201', 'javelin-behavior-differential-diff-radios' => '9dae5f20',
'javelin-behavior-differential-dropdown-menus' => '310cd201', 'javelin-behavior-differential-dropdown-menus' => '9dae5f20',
'javelin-behavior-differential-edit-inline-comments' => '310cd201', 'javelin-behavior-differential-edit-inline-comments' => '9dae5f20',
'javelin-behavior-differential-feedback-preview' => '310cd201', 'javelin-behavior-differential-feedback-preview' => '9dae5f20',
'javelin-behavior-differential-keyboard-navigation' => '310cd201', 'javelin-behavior-differential-keyboard-navigation' => '9dae5f20',
'javelin-behavior-differential-populate' => '310cd201', 'javelin-behavior-differential-populate' => '9dae5f20',
'javelin-behavior-differential-show-more' => '310cd201', 'javelin-behavior-differential-show-more' => '9dae5f20',
'javelin-behavior-differential-toggle-files' => '310cd201', 'javelin-behavior-differential-toggle-files' => '9dae5f20',
'javelin-behavior-differential-user-select' => '310cd201', 'javelin-behavior-differential-user-select' => '9dae5f20',
'javelin-behavior-diffusion-commit-graph' => 'f96657b8', 'javelin-behavior-diffusion-commit-graph' => 'f96657b8',
'javelin-behavior-diffusion-pull-lastmodified' => 'f96657b8', 'javelin-behavior-diffusion-pull-lastmodified' => 'f96657b8',
'javelin-behavior-error-log' => '032118cf', 'javelin-behavior-error-log' => '032118cf',
'javelin-behavior-global-drag-and-drop' => 'b3c1b6e7', 'javelin-behavior-global-drag-and-drop' => 'ff199687',
'javelin-behavior-konami' => 'b3c1b6e7', 'javelin-behavior-konami' => 'ff199687',
'javelin-behavior-lightbox-attachments' => 'b3c1b6e7', 'javelin-behavior-lightbox-attachments' => 'ff199687',
'javelin-behavior-maniphest-batch-selector' => '7707de41', 'javelin-behavior-maniphest-batch-selector' => '7707de41',
'javelin-behavior-maniphest-subpriority-editor' => '7707de41', 'javelin-behavior-maniphest-subpriority-editor' => '7707de41',
'javelin-behavior-maniphest-transaction-controls' => '7707de41', 'javelin-behavior-maniphest-transaction-controls' => '7707de41',
'javelin-behavior-maniphest-transaction-expand' => '7707de41', 'javelin-behavior-maniphest-transaction-expand' => '7707de41',
'javelin-behavior-maniphest-transaction-preview' => '7707de41', 'javelin-behavior-maniphest-transaction-preview' => '7707de41',
'javelin-behavior-phabricator-active-nav' => 'b3c1b6e7', 'javelin-behavior-phabricator-active-nav' => 'ff199687',
'javelin-behavior-phabricator-autofocus' => 'b3c1b6e7', 'javelin-behavior-phabricator-autofocus' => 'ff199687',
'javelin-behavior-phabricator-home-reveal-tiles' => 'b3c1b6e7', 'javelin-behavior-phabricator-home-reveal-tiles' => 'ff199687',
'javelin-behavior-phabricator-keyboard-shortcuts' => 'b3c1b6e7', 'javelin-behavior-phabricator-keyboard-shortcuts' => 'ff199687',
'javelin-behavior-phabricator-nav' => 'b3c1b6e7', 'javelin-behavior-phabricator-nav' => 'ff199687',
'javelin-behavior-phabricator-object-selector' => '310cd201', 'javelin-behavior-phabricator-object-selector' => '9dae5f20',
'javelin-behavior-phabricator-oncopy' => 'b3c1b6e7', 'javelin-behavior-phabricator-oncopy' => 'ff199687',
'javelin-behavior-phabricator-remarkup-assist' => 'b3c1b6e7', 'javelin-behavior-phabricator-remarkup-assist' => 'ff199687',
'javelin-behavior-phabricator-search-typeahead' => 'b3c1b6e7', 'javelin-behavior-phabricator-search-typeahead' => 'ff199687',
'javelin-behavior-phabricator-tooltips' => 'b3c1b6e7', 'javelin-behavior-phabricator-tooltips' => 'ff199687',
'javelin-behavior-phabricator-watch-anchor' => 'b3c1b6e7', 'javelin-behavior-phabricator-watch-anchor' => 'ff199687',
'javelin-behavior-refresh-csrf' => 'b3c1b6e7', 'javelin-behavior-refresh-csrf' => 'ff199687',
'javelin-behavior-repository-crossreference' => '310cd201', 'javelin-behavior-repository-crossreference' => '9dae5f20',
'javelin-behavior-toggle-class' => 'b3c1b6e7', 'javelin-behavior-toggle-class' => 'ff199687',
'javelin-behavior-workflow' => 'b3c1b6e7', 'javelin-behavior-workflow' => 'ff199687',
'javelin-dom' => '1c6f020b', 'javelin-dom' => '1c6f020b',
'javelin-event' => '1c6f020b', 'javelin-event' => '1c6f020b',
'javelin-install' => '1c6f020b', 'javelin-install' => '1c6f020b',
@ -3669,48 +3703,48 @@ celerity_register_resource_map(array(
'javelin-util' => '1c6f020b', 'javelin-util' => '1c6f020b',
'javelin-vector' => '1c6f020b', 'javelin-vector' => '1c6f020b',
'javelin-workflow' => '1c6f020b', 'javelin-workflow' => '1c6f020b',
'lightbox-attachment-css' => '023adc14', 'lightbox-attachment-css' => '0cb71c48',
'maniphest-task-summary-css' => 'e30a3fa8', 'maniphest-task-summary-css' => 'e30a3fa8',
'maniphest-transaction-detail-css' => 'e30a3fa8', 'maniphest-transaction-detail-css' => 'e30a3fa8',
'phabricator-busy' => 'b3c1b6e7', 'phabricator-busy' => 'ff199687',
'phabricator-content-source-view-css' => 'ec01d039', 'phabricator-content-source-view-css' => 'ec01d039',
'phabricator-core-buttons-css' => '023adc14', 'phabricator-core-buttons-css' => '0cb71c48',
'phabricator-core-css' => '023adc14', 'phabricator-core-css' => '0cb71c48',
'phabricator-crumbs-view-css' => '023adc14', 'phabricator-crumbs-view-css' => '0cb71c48',
'phabricator-directory-css' => '023adc14', 'phabricator-directory-css' => '0cb71c48',
'phabricator-drag-and-drop-file-upload' => '310cd201', 'phabricator-drag-and-drop-file-upload' => '9dae5f20',
'phabricator-dropdown-menu' => 'b3c1b6e7', 'phabricator-dropdown-menu' => 'ff199687',
'phabricator-file-upload' => 'b3c1b6e7', 'phabricator-file-upload' => 'ff199687',
'phabricator-filetree-view-css' => '023adc14', 'phabricator-filetree-view-css' => '0cb71c48',
'phabricator-flag-css' => '023adc14', 'phabricator-flag-css' => '0cb71c48',
'phabricator-form-view-css' => '023adc14', 'phabricator-form-view-css' => '0cb71c48',
'phabricator-header-view-css' => '023adc14', 'phabricator-header-view-css' => '0cb71c48',
'phabricator-jump-nav' => '023adc14', 'phabricator-jump-nav' => '0cb71c48',
'phabricator-keyboard-shortcut' => 'b3c1b6e7', 'phabricator-keyboard-shortcut' => 'ff199687',
'phabricator-keyboard-shortcut-manager' => 'b3c1b6e7', 'phabricator-keyboard-shortcut-manager' => 'ff199687',
'phabricator-main-menu-view' => '023adc14', 'phabricator-main-menu-view' => '0cb71c48',
'phabricator-menu-item' => 'b3c1b6e7', 'phabricator-menu-item' => 'ff199687',
'phabricator-nav-view-css' => '023adc14', 'phabricator-nav-view-css' => '0cb71c48',
'phabricator-notification' => 'b3c1b6e7', 'phabricator-notification' => 'ff199687',
'phabricator-notification-css' => '023adc14', 'phabricator-notification-css' => '0cb71c48',
'phabricator-notification-menu-css' => '023adc14', 'phabricator-notification-menu-css' => '0cb71c48',
'phabricator-object-item-list-view-css' => '023adc14', 'phabricator-object-item-list-view-css' => '0cb71c48',
'phabricator-object-selector-css' => 'ec01d039', 'phabricator-object-selector-css' => 'ec01d039',
'phabricator-paste-file-upload' => 'b3c1b6e7', 'phabricator-paste-file-upload' => 'ff199687',
'phabricator-prefab' => 'b3c1b6e7', 'phabricator-prefab' => 'ff199687',
'phabricator-project-tag-css' => 'e30a3fa8', 'phabricator-project-tag-css' => 'e30a3fa8',
'phabricator-remarkup-css' => '023adc14', 'phabricator-remarkup-css' => '0cb71c48',
'phabricator-shaped-request' => '310cd201', 'phabricator-shaped-request' => '9dae5f20',
'phabricator-side-menu-view-css' => '023adc14', 'phabricator-side-menu-view-css' => '0cb71c48',
'phabricator-standard-page-view' => '023adc14', 'phabricator-standard-page-view' => '0cb71c48',
'phabricator-textareautils' => 'b3c1b6e7', 'phabricator-textareautils' => 'ff199687',
'phabricator-tooltip' => 'b3c1b6e7', 'phabricator-tooltip' => 'ff199687',
'phabricator-transaction-view-css' => '023adc14', 'phabricator-transaction-view-css' => '0cb71c48',
'phabricator-zindex-css' => '023adc14', 'phabricator-zindex-css' => '0cb71c48',
'sprite-apps-large-css' => '023adc14', 'sprite-apps-large-css' => '0cb71c48',
'sprite-gradient-css' => '023adc14', 'sprite-gradient-css' => '0cb71c48',
'sprite-icon-css' => '023adc14', 'sprite-icon-css' => '0cb71c48',
'sprite-menu-css' => '023adc14', 'sprite-menu-css' => '0cb71c48',
'syntax-highlighting-css' => '023adc14', 'syntax-highlighting-css' => '0cb71c48',
), ),
)); ));

View file

@ -674,6 +674,7 @@ phutil_register_library_map(array(
'PhabricatorApplicationTransactionView' => 'applications/transactions/view/PhabricatorApplicationTransactionView.php', 'PhabricatorApplicationTransactionView' => 'applications/transactions/view/PhabricatorApplicationTransactionView.php',
'PhabricatorApplicationTransactions' => 'applications/transactions/application/PhabricatorApplicationTransactions.php', 'PhabricatorApplicationTransactions' => 'applications/transactions/application/PhabricatorApplicationTransactions.php',
'PhabricatorApplicationUIExamples' => 'applications/uiexample/application/PhabricatorApplicationUIExamples.php', 'PhabricatorApplicationUIExamples' => 'applications/uiexample/application/PhabricatorApplicationUIExamples.php',
'PhabricatorApplicationUninstallController' => 'applications/meta/controller/PhabricatorApplicationUninstallController.php',
'PhabricatorApplicationsController' => 'applications/meta/controller/PhabricatorApplicationsController.php', 'PhabricatorApplicationsController' => 'applications/meta/controller/PhabricatorApplicationsController.php',
'PhabricatorApplicationsListController' => 'applications/meta/controller/PhabricatorApplicationsListController.php', 'PhabricatorApplicationsListController' => 'applications/meta/controller/PhabricatorApplicationsListController.php',
'PhabricatorAuditActionConstants' => 'applications/audit/constants/PhabricatorAuditActionConstants.php', 'PhabricatorAuditActionConstants' => 'applications/audit/constants/PhabricatorAuditActionConstants.php',
@ -1478,6 +1479,7 @@ phutil_register_library_map(array(
'celerity_get_resource_uri' => 'infrastructure/celerity/api.php', 'celerity_get_resource_uri' => 'infrastructure/celerity/api.php',
'celerity_register_resource_map' => 'infrastructure/celerity/map.php', 'celerity_register_resource_map' => 'infrastructure/celerity/map.php',
'javelin_render_tag' => 'infrastructure/javelin/markup.php', 'javelin_render_tag' => 'infrastructure/javelin/markup.php',
'javelin_tag' => 'infrastructure/javelin/markup.php',
'phabricator_date' => 'view/viewutils.php', 'phabricator_date' => 'view/viewutils.php',
'phabricator_datetime' => 'view/viewutils.php', 'phabricator_datetime' => 'view/viewutils.php',
'phabricator_format_bytes' => 'view/viewutils.php', 'phabricator_format_bytes' => 'view/viewutils.php',
@ -2105,6 +2107,7 @@ phutil_register_library_map(array(
'PhabricatorApplicationTransactionView' => 'AphrontView', 'PhabricatorApplicationTransactionView' => 'AphrontView',
'PhabricatorApplicationTransactions' => 'PhabricatorApplication', 'PhabricatorApplicationTransactions' => 'PhabricatorApplication',
'PhabricatorApplicationUIExamples' => 'PhabricatorApplication', 'PhabricatorApplicationUIExamples' => 'PhabricatorApplication',
'PhabricatorApplicationUninstallController' => 'PhabricatorApplicationsController',
'PhabricatorApplicationsController' => 'PhabricatorController', 'PhabricatorApplicationsController' => 'PhabricatorController',
'PhabricatorApplicationsListController' => 'PhabricatorApplicationsController', 'PhabricatorApplicationsListController' => 'PhabricatorApplicationsController',
'PhabricatorAuditAddCommentController' => 'PhabricatorAuditController', 'PhabricatorAuditAddCommentController' => 'PhabricatorAuditController',

View file

@ -6,6 +6,10 @@ final class PhabricatorApplicationAuth extends PhabricatorApplication {
return false; return false;
} }
public function canUninstall() {
return false;
}
public function buildMainMenuItems( public function buildMainMenuItems(
PhabricatorUser $user, PhabricatorUser $user,
PhabricatorController $controller = null) { PhabricatorController $controller = null) {

View file

@ -62,10 +62,25 @@ abstract class PhabricatorApplication {
return true; return true;
} }
public function isInstalled() {
$uninstalled =
PhabricatorEnv::getEnvConfig('phabricator.uninstalled-applications');
if (isset($uninstalled[get_class($this)])) {
return false;
} else {
return true;
}
}
public function isBeta() { public function isBeta() {
return false; return false;
} }
public function canUninstall() {
return true;
}
public function getPHID() { public function getPHID() {
return 'PHID-APPS-'.get_class($this); return 'PHID-APPS-'.get_class($this);
} }
@ -212,6 +227,22 @@ abstract class PhabricatorApplication {
/* -( Application Management )--------------------------------------------- */ /* -( Application Management )--------------------------------------------- */
public static function getAllApplications() {
$classes = id(new PhutilSymbolLoader())
->setAncestorClass(__CLASS__)
->setConcreteOnly(true)
->selectAndLoadSymbols();
$apps = array();
foreach ($classes as $class) {
$app = newv($class['name'], array());
$apps[] = $app;
}
return $apps;
}
public static function getAllInstalledApplications() { public static function getAllInstalledApplications() {
static $applications; static $applications;
@ -219,6 +250,11 @@ abstract class PhabricatorApplication {
$show_beta = $show_beta =
PhabricatorEnv::getEnvConfig('phabricator.show-beta-applications'); PhabricatorEnv::getEnvConfig('phabricator.show-beta-applications');
$uninstalled =
PhabricatorEnv::getEnvConfig('phabricator.uninstalled-applications');
if (empty($applications)) { if (empty($applications)) {
$classes = id(new PhutilSymbolLoader()) $classes = id(new PhutilSymbolLoader())
->setAncestorClass(__CLASS__) ->setAncestorClass(__CLASS__)
@ -227,22 +263,29 @@ abstract class PhabricatorApplication {
$apps = array(); $apps = array();
foreach ($classes as $class) { foreach ($classes as $class) {
$app = newv($class['name'], array());
if (!$app->isEnabled()) {
continue;
}
if (!$show_beta && $app->isBeta()) { if (isset($uninstalled[$class['name']])) {
continue; continue;
}
$apps[] = $app;
} }
$app = newv($class['name'], array());
if (!$app->isEnabled()) {
continue;
}
if (!$show_beta && $app->isBeta()) {
continue;
}
$apps[] = $app;
}
$applications = $apps; $applications = $apps;
} }
return $applications; return $applications;
} }
} }

View file

@ -18,6 +18,10 @@ final class PhabricatorApplicationConfig extends PhabricatorApplication {
return self::GROUP_ADMIN; return self::GROUP_ADMIN;
} }
public function canUninstall() {
return false;
}
public function getRoutes() { public function getRoutes() {
return array( return array(
'/config/' => array( '/config/' => array(

View file

@ -4,6 +4,26 @@ final class PhabricatorSetupCheckBaseURI extends PhabricatorSetupCheck {
protected function executeChecks() { protected function executeChecks() {
$base_uri = PhabricatorEnv::getEnvConfig('phabricator.base-uri'); $base_uri = PhabricatorEnv::getEnvConfig('phabricator.base-uri');
if (strpos($_SERVER['HTTP_HOST'], '.') === false) {
$summary = pht(
'The domain does not contain a dot. This is necessary for some web '.
'browsers to be able to set cookies.');
$message = pht(
'The domain in the base URI must contain a dot ("."), e.g. '.
'"http://example.com", not just a bare name like "http://example/". '.
'Some web browsers will not set cookies on domains with no TLD.');
$this
->newIssue('config.phabricator.domain')
->setShortName(pht('Dotless Domain'))
->setName(pht('No Dot Character in Domain'))
->setSummary($summary)
->setMessage($message)
->setIsFatal(true);
}
if ($base_uri) { if ($base_uri) {
return; return;
} }

View file

@ -128,6 +128,11 @@ final class PhabricatorCoreConfigOptions
$this->newOption('test.value', 'wild', null) $this->newOption('test.value', 'wild', null)
->setLocked(true) ->setLocked(true)
->setDescription(pht('Unit test value.')), ->setDescription(pht('Unit test value.')),
$this->newOption('phabricator.uninstalled-applications', 'set', array())
->setLocked(true)
->setDescription(
pht('Array containing list of Uninstalled applications.')
),
); );
} }

View file

@ -107,9 +107,9 @@ abstract class ConpherenceController extends PhabricatorController {
$nav->addClass('conpherence-menu'); $nav->addClass('conpherence-menu');
$nav->setMenuID('conpherence-menu'); $nav->setMenuID('conpherence-menu');
$nav->addFilter( $nav->addButton(
'new', 'new',
pht('New Conpherence'), pht('New Conversation'),
$this->getApplicationURI('new/') $this->getApplicationURI('new/')
); );
$nav->addLabel(pht('Unread')); $nav->addLabel(pht('Unread'));
@ -183,7 +183,7 @@ abstract class ConpherenceController extends PhabricatorController {
$crumbs $crumbs
->addAction( ->addAction(
id(new PhabricatorMenuItemView()) id(new PhabricatorMenuItemView())
->setName(pht('New Conpherence')) ->setName(pht('New Conversation'))
->setHref($this->getApplicationURI('new/')) ->setHref($this->getApplicationURI('new/'))
->setIcon('create') ->setIcon('create')
) )

View file

@ -12,7 +12,7 @@ final class ConpherenceNewController extends ConpherenceController {
$conpherence = id(new ConpherenceThread()) $conpherence = id(new ConpherenceThread())
->attachParticipants(array()) ->attachParticipants(array())
->attachFilePHIDs(array()); ->attachFilePHIDs(array());
$title = pht('New Conpherence'); $title = pht('New Conversation');
$participants = array(); $participants = array();
$message = ''; $message = '';
$files = array(); $files = array();

View file

@ -26,6 +26,10 @@ final class PhabricatorApplicationDaemons extends PhabricatorApplication {
return self::GROUP_ADMIN; return self::GROUP_ADMIN;
} }
public function canUninstall() {
return false;
}
public function getRoutes() { public function getRoutes() {
return array( return array(
'/daemon/' => array( '/daemon/' => array(

View file

@ -176,14 +176,17 @@ final class DifferentialRevisionViewController extends DifferentialController {
$limit = 100; $limit = 100;
$large = $request->getStr('large'); $large = $request->getStr('large');
if (count($changesets) > $limit && !$large) { if (count($changesets) > $limit && !$large) {
$count = number_format(count($changesets)); $count = count($changesets);
$warning = new AphrontErrorView(); $warning = new AphrontErrorView();
$warning->setTitle('Very Large Diff'); $warning->setTitle('Very Large Diff');
$warning->setSeverity(AphrontErrorView::SEVERITY_WARNING); $warning->setSeverity(AphrontErrorView::SEVERITY_WARNING);
$warning->appendChild( $warning->appendChild(
'<p>'.pht('This diff is very large and affects %d files. Load '. pht(
'each file individually. ', $count). 'This diff is very large and affects %2$s files. Load each file '.
"<strong>". 'individually.',
$count,
PhutilTranslator::getInstance()->formatNumber($count)).
" <strong>".
phutil_tag( phutil_tag(
'a', 'a',
array( array(

View file

@ -29,8 +29,9 @@ final class DifferentialBlameRevisionFieldSpecification
public function renderEditControl() { public function renderEditControl() {
return id(new AphrontFormTextControl()) return id(new AphrontFormTextControl())
->setLabel('Blame Revision') ->setLabel(pht('Blame Revision'))
->setCaption('Revision which broke the stuff which this change fixes.') ->setCaption(
pht('Revision which broke the stuff which this change fixes.'))
->setName($this->getStorageKey()) ->setName($this->getStorageKey())
->setValue($this->value); ->setValue($this->value);
} }
@ -40,7 +41,7 @@ final class DifferentialBlameRevisionFieldSpecification
} }
public function renderLabelForRevisionView() { public function renderLabelForRevisionView() {
return 'Blame Revision:'; return pht('Blame Revision:');
} }
public function renderValueForRevisionView() { public function renderValueForRevisionView() {

View file

@ -14,6 +14,10 @@ final class PhabricatorApplicationFeed extends PhabricatorApplication {
return 'feed'; return 'feed';
} }
public function canUninstall() {
return false;
}
public function getRoutes() { public function getRoutes() {
return array( return array(
'/feed/' => array( '/feed/' => array(

View file

@ -228,7 +228,7 @@ final class PhabricatorImageTransformer {
$text_height = abs($bbox[3] - $bbox[5]); $text_height = abs($bbox[3] - $bbox[5]);
$text_width = abs($bbox[0] - $bbox[2]); $text_width = abs($bbox[0] - $bbox[2]);
return array( return array(
"doesfit" => ($text_height * 1.05 <= imagesy($img) "doesfit" => ($text_height * 1.05 <= imagesy($img) / 2
&& $text_width * 1.05 <= imagesx($img)), && $text_width * 1.05 <= imagesx($img)),
"txtwidth" => $text_width, "txtwidth" => $text_width,
"txtheight" => $text_height, "txtheight" => $text_height,

View file

@ -30,6 +30,10 @@ final class PhabricatorApplicationFiles extends PhabricatorApplication {
return $this->getBaseURI().'upload/'; return $this->getBaseURI().'upload/';
} }
public function canUninstall() {
return false;
}
public function getRoutes() { public function getRoutes() {
return array( return array(
'/F(?P<id>[1-9]\d*)' => 'PhabricatorFileShortcutController', '/F(?P<id>[1-9]\d*)' => 'PhabricatorFileShortcutController',

View file

@ -2,6 +2,10 @@
final class PhabricatorApplicationApplications extends PhabricatorApplication { final class PhabricatorApplicationApplications extends PhabricatorApplication {
public function canUninstall() {
return false;
}
public function getBaseURI() { public function getBaseURI() {
return '/applications/'; return '/applications/';
} }
@ -28,7 +32,8 @@ final class PhabricatorApplicationApplications extends PhabricatorApplication {
'' => 'PhabricatorApplicationsListController', '' => 'PhabricatorApplicationsListController',
'view/(?P<application>\w+)/' => 'view/(?P<application>\w+)/' =>
'PhabricatorApplicationDetailViewController', 'PhabricatorApplicationDetailViewController',
'(?P<application>\w+)/(?P<action>install|uninstall)/' =>
'PhabricatorApplicationUninstallController',
), ),
); );

View file

@ -14,12 +14,12 @@ final class PhabricatorApplicationDetailViewController
$user = $request->getUser(); $user = $request->getUser();
$selected = null; $selected = null;
$applications = PhabricatorApplication::getAllInstalledApplications(); $applications = PhabricatorApplication::getAllApplications();
foreach ($applications as $application) { foreach ($applications as $application) {
if (get_class($application) == $this->application) { if (get_class($application) == $this->application) {
$selected = $application; $selected = $application;
break; break;
} }
} }
@ -35,27 +35,33 @@ final class PhabricatorApplicationDetailViewController
->setName(pht('Applications')) ->setName(pht('Applications'))
->setHref($this->getApplicationURI())); ->setHref($this->getApplicationURI()));
$properties = $this->buildPropertyView($selected); $properties = $this->buildPropertyView($selected);
$actions = $this->buildActionView($user); $actions = $this->buildActionView($user, $selected);
return $this->buildApplicationPage( return $this->buildApplicationPage(
array( array(
$crumbs, $crumbs,
id(new PhabricatorHeaderView())->setHeader($title), id(new PhabricatorHeaderView())->setHeader($title),
$actions, $actions,
$properties, $properties,
), ),
array( array(
'title' => $title, 'title' => $title,
'device' => true, 'device' => true,
)); ));
} }
private function buildPropertyView(PhabricatorApplication $selected) { private function buildPropertyView(PhabricatorApplication $selected) {
$properties = new PhabricatorPropertyListView(); $properties = new PhabricatorPropertyListView();
$properties->addProperty( if ($selected->isInstalled()) {
pht('Status'), pht('Installed')); $properties->addProperty(
pht('Status'), pht('Installed'));
} else {
$properties->addProperty(
pht('Status'), pht('Uninstalled'));
}
$properties->addProperty( $properties->addProperty(
pht('Description'), $selected->getShortDescription()); pht('Description'), $selected->getShortDescription());
@ -63,15 +69,33 @@ final class PhabricatorApplicationDetailViewController
return $properties; return $properties;
} }
private function buildActionView(PhabricatorUser $user) { private function buildActionView(
PhabricatorUser $user, PhabricatorApplication $selected) {
return id(new PhabricatorActionListView()) if ($selected->canUninstall()) {
->setUser($user) if ($selected->isInstalled()) {
->addAction(
id(new PhabricatorActionView()) return id(new PhabricatorActionListView())
->setName(pht('Uninstall')) ->setUser($user)
->setIcon('delete') ->addAction(
); id(new PhabricatorActionView())
->setName(pht('Uninstall'))
->setIcon('delete')
->setHref(
$this->getApplicationURI(get_class($selected).'/uninstall/'))
);
} else {
return id(new PhabricatorActionListView())
->setUser($user)
->addAction(
id(new PhabricatorActionView())
->setName(pht('Install'))
->setIcon('new')
->setHref(
$this->getApplicationURI(get_class($selected).'/install/'))
);
}
}
} }
} }

View file

@ -0,0 +1,93 @@
<?php
final class PhabricatorApplicationUninstallController
extends PhabricatorApplicationsController {
private $application;
private $action;
public function willProcessRequest(array $data) {
$this->application = $data['application'];
$this->action = $data['action'];
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$app_name = substr($this->application, strlen('PhabricatorApplication'));
if ($request->isDialogFormPost()) {
$this->manageApplication();
return id(new AphrontRedirectResponse())->setURI('/applications/');
}
if ($this->action == 'install') {
$dialog = id(new AphrontDialogView())
->setUser($user)
->setTitle('Confirmation')
->appendChild('Install '. $app_name. ' application ?')
->addSubmitButton('Install')
->addCancelButton('/applications/view/'.$this->application);
} else {
$dialog = id(new AphrontDialogView())
->setUser($user)
->setTitle('Confirmation')
->appendChild('Really Uninstall '. $app_name. ' application ?')
->addSubmitButton('Uninstall')
->addCancelButton('/applications/view/'.$this->application);
}
return id(new AphrontDialogResponse())->setDialog($dialog);
}
public function manageApplication() {
$key = 'phabricator.uninstalled-applications';
$config_entry = id(new PhabricatorConfigEntry())
->loadOneWhere(
'configKey = %s AND namespace = %s',
$key,
'default');
if (!$config_entry) {
$config_entry = id(new PhabricatorConfigEntry())
->setConfigKey($key)
->setNamespace('default');
}
$list = $config_entry->getValue();
$uninstalled = PhabricatorEnv::getEnvConfig($key);
if ($uninstalled[$this->application]) {
unset($list[$this->application]);
} else {
$list[$this->application] = true;
}
$xaction = id(new PhabricatorConfigTransaction())
->setTransactionType(PhabricatorConfigTransaction::TYPE_EDIT)
->setNewValue(
array(
'deleted' => false,
'value' => $list
));
$editor = id(new PhabricatorConfigEditor())
->setActor($this->getRequest()->getUser())
->setContinueOnNoEffect(true)
->setContentSource(
PhabricatorContentSource::newForSource(
PhabricatorContentSource::SOURCE_WEB,
array(
'ip' => $this->getRequest()->getRemoteAddr(),
)));
$editor->applyTransactions($config_entry, array($xaction));
}
}

View file

@ -10,7 +10,7 @@ final class PhabricatorApplicationsListController
$nav = $this->buildSideNavView(); $nav = $this->buildSideNavView();
$nav->selectFilter('/'); $nav->selectFilter('/');
$applications = PhabricatorApplication::getAllInstalledApplications(); $applications = PhabricatorApplication::getAllApplications();
$list = $this->buildInstalledApplicationsList($applications); $list = $this->buildInstalledApplicationsList($applications);

View file

@ -7,7 +7,7 @@ final class PhabricatorApplicationMetaMTA extends PhabricatorApplication {
} }
public function getShortDescription() { public function getShortDescription() {
return 'View Mail Logs'; return pht('View Mail Logs');
} }
public function getIconName() { public function getIconName() {
@ -22,6 +22,10 @@ final class PhabricatorApplicationMetaMTA extends PhabricatorApplication {
return self::GROUP_ADMIN; return self::GROUP_ADMIN;
} }
public function canUninstall() {
return false;
}
public function getRoutes() { public function getRoutes() {
return array( return array(
$this->getBaseURI() => array( $this->getBaseURI() => array(

View file

@ -10,14 +10,14 @@ abstract class PhabricatorMetaMTAController extends PhabricatorController {
$nav = new AphrontSideNavFilterView(); $nav = new AphrontSideNavFilterView();
$nav->setBaseURI(new PhutilURI($this->getApplicationURI())); $nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
$nav->addLabel('Mail Logs'); $nav->addLabel(pht('Mail Logs'));
$nav->addFilter('sent', 'Sent Mail', $this->getApplicationURI()); $nav->addFilter('sent', pht('Sent Mail'), $this->getApplicationURI());
$nav->addFilter('received', 'Received Mail'); $nav->addFilter('received', pht('Received Mail'));
if ($this->getRequest()->getUser()->getIsAdmin()) { if ($this->getRequest()->getUser()->getIsAdmin()) {
$nav->addLabel('Diagnostics'); $nav->addLabel(pht('Diagnostics'));
$nav->addFilter('send', 'Send Test'); $nav->addFilter('send', pht('Send Test'));
$nav->addFilter('receive', 'Receive Test'); $nav->addFilter('receive', pht('Receive Test'));
} }
return $nav; return $nav;

View file

@ -74,19 +74,19 @@ final class PhabricatorMetaMTAListController
'class' => 'button small grey', 'class' => 'button small grey',
'href' => $this->getApplicationURI('/view/'.$mail->getID().'/'), 'href' => $this->getApplicationURI('/view/'.$mail->getID().'/'),
), ),
'View'), pht('View')),
); );
} }
$table = new AphrontTableView($rows); $table = new AphrontTableView($rows);
$table->setHeaders( $table->setHeaders(
array( array(
'Status', pht('Status'),
'Retry', pht('Retry'),
'Next', pht('Next'),
'Created', pht('Created'),
'Updated', pht('Updated'),
'Subject', pht('Subject'),
'', '',
)); ));
$table->setColumnClasses( $table->setColumnClasses(
@ -103,8 +103,9 @@ final class PhabricatorMetaMTAListController
// Render the whole page. // Render the whole page.
$panel = new AphrontPanelView(); $panel = new AphrontPanelView();
$panel->appendChild($table); $panel->appendChild($table);
$panel->setHeader('MetaMTA Messages'); $panel->setHeader(pht('MetaMTA Messages'));
$panel->appendChild($pager); $panel->appendChild($pager);
$panel->setNoBackground();
$nav = $this->buildSideNavView(); $nav = $this->buildSideNavView();
$nav->selectFilter('sent'); $nav->selectFilter('sent');
@ -113,7 +114,8 @@ final class PhabricatorMetaMTAListController
return $this->buildApplicationPage( return $this->buildApplicationPage(
$nav, $nav,
array( array(
'title' => 'Sent Mail', 'title' => pht('Sent Mail'),
'device' => true,
)); ));
} }
} }

View file

@ -12,7 +12,7 @@ final class PhabricatorMetaMTAReceiveController
$receiver = PhabricatorMetaMTAReceivedMail::loadReceiverObject( $receiver = PhabricatorMetaMTAReceivedMail::loadReceiverObject(
$request->getStr('obj')); $request->getStr('obj'));
if (!$receiver) { if (!$receiver) {
throw new Exception("No such task or revision!"); throw new Exception(pht("No such task or revision!"));
} }
$hash = PhabricatorMetaMTAReceivedMail::computeMailHash( $hash = PhabricatorMetaMTAReceivedMail::computeMailHash(
@ -50,25 +50,26 @@ final class PhabricatorMetaMTAReceiveController
$form->setAction($this->getApplicationURI('/receive/')); $form->setAction($this->getApplicationURI('/receive/'));
$form $form
->appendChild( ->appendChild(
'<p class="aphront-form-instructions">This form will simulate '. '<p class="aphront-form-instructions">'.
'sending mail to an object.</p>') pht('This form will simulate sending mail to an object.').
'</p>')
->appendChild( ->appendChild(
id(new AphrontFormTextControl()) id(new AphrontFormTextControl())
->setLabel('To') ->setLabel(pht('To'))
->setName('obj') ->setName('obj')
->setCaption('e.g. <tt>D1234</tt> or <tt>T1234</tt>')) ->setCaption(pht('e.g. <tt>D1234</tt> or <tt>T1234</tt>')))
->appendChild( ->appendChild(
id(new AphrontFormTextAreaControl()) id(new AphrontFormTextAreaControl())
->setLabel('Body') ->setLabel(pht('Body'))
->setName('body')) ->setName('body'))
->appendChild( ->appendChild(
id(new AphrontFormSubmitControl()) id(new AphrontFormSubmitControl())
->setValue('Receive Mail')); ->setValue(pht('Receive Mail')));
$panel = new AphrontPanelView(); $panel = new AphrontPanelView();
$panel->setHeader('Receive Email'); $panel->setHeader(pht('Receive Email'));
$panel->appendChild($form); $panel->appendChild($form);
$panel->setWidth(AphrontPanelView::WIDTH_FORM); $panel->setNoBackground();
$nav = $this->buildSideNavView(); $nav = $this->buildSideNavView();
$nav->selectFilter('receive'); $nav->selectFilter('receive');
@ -77,7 +78,8 @@ final class PhabricatorMetaMTAReceiveController
return $this->buildApplicationPage( return $this->buildApplicationPage(
$nav, $nav,
array( array(
'title' => 'Receive Test', 'title' => pht('Receive Test'),
'device' => true,
)); ));
} }

View file

@ -45,12 +45,12 @@ final class PhabricatorMetaMTAReceivedListController
$table = new AphrontTableView($rows); $table = new AphrontTableView($rows);
$table->setHeaders( $table->setHeaders(
array( array(
'ID', pht('ID'),
'Date', pht('Date'),
'Time', pht('Time'),
'Author', pht('Author'),
'Object', pht('Object'),
'Message', pht('Message'),
)); ));
$table->setColumnClasses( $table->setColumnClasses(
array( array(
@ -63,9 +63,10 @@ final class PhabricatorMetaMTAReceivedListController
)); ));
$panel = new AphrontPanelView(); $panel = new AphrontPanelView();
$panel->setHeader('Received Mail'); $panel->setHeader(pht('Received Mail'));
$panel->appendChild($table); $panel->appendChild($table);
$panel->appendChild($pager); $panel->appendChild($pager);
$panel->setNoBackground();
$nav = $this->buildSideNavView(); $nav = $this->buildSideNavView();
$nav->selectFilter('received'); $nav->selectFilter('received');
@ -74,7 +75,8 @@ final class PhabricatorMetaMTAReceivedListController
return $this->buildApplicationPage( return $this->buildApplicationPage(
$nav, $nav,
array( array(
'title' => 'Received Mail', 'title' => pht('Received Mail'),
'device' => true,
)); ));
} }
} }

View file

@ -42,8 +42,8 @@ final class PhabricatorMetaMTASendController
} }
$failure_caption = $failure_caption =
"Enter a number to simulate that many consecutive send failures before ". pht("Enter a number to simulate that many consecutive send failures ".
"really attempting to deliver via the underlying MTA."; "brefore really attempting to deliver via the underlying MTA.");
$doclink_href = PhabricatorEnv::getDoclink( $doclink_href = PhabricatorEnv::getDoclink(
'article/Configuring_Outbound_Email.html'); 'article/Configuring_Outbound_Email.html');
@ -54,11 +54,12 @@ final class PhabricatorMetaMTASendController
'href' => $doclink_href, 'href' => $doclink_href,
'target' => '_blank', 'target' => '_blank',
), ),
'Configuring Outbound Email'); pht('Configuring Outbound Email'));
$instructions = $instructions =
'<p class="aphront-form-instructions">This form will send a normal '. '<p class="aphront-form-instructions">'.
'email using the settings you have configured for Phabricator. For more '. pht('This form will send a normal email using the settings you have '.
'information, see '.$doclink.'.</p>'; 'configured for Phabricator. For more information, see %s.', $doclink).
'</p>';
$adapter = PhabricatorEnv::getEnvConfig('metamta.mail-adapter'); $adapter = PhabricatorEnv::getEnvConfig('metamta.mail-adapter');
$warning = null; $warning = null;
@ -67,11 +68,11 @@ final class PhabricatorMetaMTASendController
$warning->setTitle('Email is Disabled'); $warning->setTitle('Email is Disabled');
$warning->setSeverity(AphrontErrorView::SEVERITY_WARNING); $warning->setSeverity(AphrontErrorView::SEVERITY_WARNING);
$warning->appendChild( $warning->appendChild(
'<p>This installation of Phabricator is currently set to use '. '<p>'.pht('This installation of Phabricator is currently set to use '.
'<tt>PhabricatorMailImplementationTestAdapter</tt> to deliver '. '<tt>PhabricatorMailImplementationTestAdapter</tt> to deliver '.
'outbound email. This completely disables outbound email! All '. 'outbound email. This completely disables outbound email! All '.
'outbound email will be thrown in a deep, dark hole until you '. 'outbound email will be thrown in a deep, dark hole until you '.
'configure a real adapter.</p>'); 'configure a real adapter.').'</p>');
} }
$phdlink_href = PhabricatorEnv::getDoclink( $phdlink_href = PhabricatorEnv::getDoclink(
@ -91,49 +92,49 @@ final class PhabricatorMetaMTASendController
->appendChild($instructions) ->appendChild($instructions)
->appendChild( ->appendChild(
id(new AphrontFormStaticControl()) id(new AphrontFormStaticControl())
->setLabel('Adapter') ->setLabel(pht('Adapter'))
->setValue($adapter)) ->setValue($adapter))
->appendChild( ->appendChild(
id(new AphrontFormTokenizerControl()) id(new AphrontFormTokenizerControl())
->setLabel('To') ->setLabel(pht('To'))
->setName('to') ->setName('to')
->setDatasource('/typeahead/common/mailable/')) ->setDatasource('/typeahead/common/mailable/'))
->appendChild( ->appendChild(
id(new AphrontFormTokenizerControl()) id(new AphrontFormTokenizerControl())
->setLabel('CC') ->setLabel(pht('CC'))
->setName('cc') ->setName('cc')
->setDatasource('/typeahead/common/mailable/')) ->setDatasource('/typeahead/common/mailable/'))
->appendChild( ->appendChild(
id(new AphrontFormTextControl()) id(new AphrontFormTextControl())
->setLabel('Subject') ->setLabel(pht('Subject'))
->setName('subject')) ->setName('subject'))
->appendChild( ->appendChild(
id(new AphrontFormTextAreaControl()) id(new AphrontFormTextAreaControl())
->setLabel('Body') ->setLabel(pht('Body'))
->setName('body')) ->setName('body'))
->appendChild( ->appendChild(
id(new AphrontFormTextControl()) id(new AphrontFormTextControl())
->setLabel('Mail Tags') ->setLabel(pht('Mail Tags'))
->setName('mailtags') ->setName('mailtags')
->setCaption( ->setCaption(
'Example: <tt>differential-cc, differential-comment</tt>')) pht('Example:').' <tt>differential-cc, differential-comment</tt>'))
->appendChild( ->appendChild(
id(new AphrontFormDragAndDropUploadControl()) id(new AphrontFormDragAndDropUploadControl())
->setLabel('Attach Files') ->setLabel(pht('Attach Files'))
->setName('files') ->setName('files')
->setActivatedClass('aphront-panel-view-drag-and-drop')) ->setActivatedClass('aphront-panel-view-drag-and-drop'))
->appendChild( ->appendChild(
id(new AphrontFormTextControl()) id(new AphrontFormTextControl())
->setLabel('Simulate Failures') ->setLabel(pht('Simulate Failures'))
->setName('failures') ->setName('failures')
->setCaption($failure_caption)) ->setCaption($failure_caption))
->appendChild( ->appendChild(
id(new AphrontFormCheckboxControl()) id(new AphrontFormCheckboxControl())
->setLabel('HTML') ->setLabel(pht('HTML'))
->addCheckbox('html', '1', 'Send as HTML email.')) ->addCheckbox('html', '1', 'Send as HTML email.'))
->appendChild( ->appendChild(
id(new AphrontFormCheckboxControl()) id(new AphrontFormCheckboxControl())
->setLabel('Bulk') ->setLabel(pht('Bulk'))
->addCheckbox('bulk', '1', 'Send with bulk email headers.')) ->addCheckbox('bulk', '1', 'Send with bulk email headers.'))
->appendChild( ->appendChild(
id(new AphrontFormCheckboxControl()) id(new AphrontFormCheckboxControl())
@ -141,18 +142,18 @@ final class PhabricatorMetaMTASendController
->addCheckbox( ->addCheckbox(
'immediately', 'immediately',
'1', '1',
'Send immediately. (Do not enqueue for daemons.)', pht('Send immediately. (Do not enqueue for daemons.)'),
PhabricatorEnv::getEnvConfig('metamta.send-immediately')) PhabricatorEnv::getEnvConfig('metamta.send-immediately'))
->setCaption('Daemons can be started with '.$phdlink.'.') ->setCaption(pht('Daemons can be started with %s.', $phdlink))
) )
->appendChild( ->appendChild(
id(new AphrontFormSubmitControl()) id(new AphrontFormSubmitControl())
->setValue('Send Mail')); ->setValue(pht('Send Mail')));
$panel = new AphrontPanelView(); $panel = new AphrontPanelView();
$panel->setHeader('Send Email'); $panel->setHeader(pht('Send Email'));
$panel->appendChild($form); $panel->appendChild($form);
$panel->setWidth(AphrontPanelView::WIDTH_FORM); $panel->setNoBackground();
$nav = $this->buildSideNavView(); $nav = $this->buildSideNavView();
$nav->selectFilter('send'); $nav->selectFilter('send');
@ -165,7 +166,8 @@ final class PhabricatorMetaMTASendController
return $this->buildApplicationPage( return $this->buildApplicationPage(
$nav, $nav,
array( array(
'title' => 'Send Test', 'title' => pht('Send Test'),
'device' => true,
)); ));
} }

View file

@ -61,7 +61,7 @@ final class PhabricatorMetaMTASendGridReceiveController
$received->processReceivedMail(); $received->processReceivedMail();
$response = new AphrontWebpageResponse(); $response = new AphrontWebpageResponse();
$response->setContent("Got it! Thanks, SendGrid!\n"); $response->setContent(pht("Got it! Thanks, SendGrid!\n"));
return $response; return $response;
} }

View file

@ -26,41 +26,43 @@ final class PhabricatorMetaMTAViewController
$form $form
->appendChild( ->appendChild(
id(new AphrontFormStaticControl()) id(new AphrontFormStaticControl())
->setLabel('Subject') ->setLabel(pht('Subject'))
->setValue($mail->getSubject())) ->setValue($mail->getSubject()))
->appendChild( ->appendChild(
id(new AphrontFormStaticControl()) id(new AphrontFormStaticControl())
->setLabel('Created') ->setLabel(pht('Created'))
->setValue(phabricator_datetime($mail->getDateCreated(), $user))) ->setValue(phabricator_datetime($mail->getDateCreated(), $user)))
->appendChild( ->appendChild(
id(new AphrontFormStaticControl()) id(new AphrontFormStaticControl())
->setLabel('Status') ->setLabel(pht('Status'))
->setValue($status)) ->setValue($status))
->appendChild( ->appendChild(
id(new AphrontFormStaticControl()) id(new AphrontFormStaticControl())
->setLabel('Retry Count') ->setLabel(pht('Retry Count'))
->setValue($mail->getRetryCount())) ->setValue($mail->getRetryCount()))
->appendChild( ->appendChild(
id(new AphrontFormStaticControl()) id(new AphrontFormStaticControl())
->setLabel('Message') ->setLabel(pht('Message'))
->setValue($mail->getMessage())) ->setValue($mail->getMessage()))
->appendChild( ->appendChild(
id(new AphrontFormStaticControl()) id(new AphrontFormStaticControl())
->setLabel('Related PHID') ->setLabel(pht('Related PHID'))
->setValue($mail->getRelatedPHID())) ->setValue($mail->getRelatedPHID()))
->appendChild( ->appendChild(
id(new AphrontFormSubmitControl()) id(new AphrontFormSubmitControl())
->addCancelButton($this->getApplicationURI(), 'Done')); ->addCancelButton($this->getApplicationURI(), pht('Done')));
$panel = new AphrontPanelView(); $panel = new AphrontPanelView();
$panel->setHeader('View Email'); $panel->setHeader(pht('View Email'));
$panel->appendChild($form); $panel->appendChild($form);
$panel->setWidth(AphrontPanelView::WIDTH_WIDE); $panel->setWidth(AphrontPanelView::WIDTH_WIDE);
$panel->setNoBackground();
return $this->buildApplicationPage( return $this->buildApplicationPage(
$panel, $panel,
array( array(
'title' => 'View Mail', 'title' => pht('View Mail'),
'device' => true,
)); ));
} }

View file

@ -26,6 +26,10 @@ final class PhabricatorApplicationPeople extends PhabricatorApplication {
return self::GROUP_ADMIN; return self::GROUP_ADMIN;
} }
public function canUninstall() {
return false;
}
public function getRoutes() { public function getRoutes() {
return array( return array(
'/people/' => array( '/people/' => array(

View file

@ -26,143 +26,171 @@ final class PhabricatorObjectHandleData {
} }
public function loadObjects() { public function loadObjects() {
$types = array(); $types = phid_group_by_type($this->phids);
foreach ($this->phids as $phid) {
$type = phid_get_type($phid);
$types[$type][] = $phid;
}
$objects = array(); $objects = array();
foreach ($types as $type => $phids) { foreach ($types as $type => $phids) {
switch ($type) { $objects += $this->loadObjectsOfType($type, $phids);
case PhabricatorPHIDConstants::PHID_TYPE_USER:
$user_dao = new PhabricatorUser();
$users = $user_dao->loadAllWhere(
'phid in (%Ls)',
$phids);
foreach ($users as $user) {
$objects[$user->getPHID()] = $user;
}
break;
case PhabricatorPHIDConstants::PHID_TYPE_CMIT:
$commit_dao = new PhabricatorRepositoryCommit();
$commits = $commit_dao->loadAllWhere(
'phid IN (%Ls)',
$phids);
$commit_data = array();
if ($commits) {
$data_dao = new PhabricatorRepositoryCommitData();
$commit_data = $data_dao->loadAllWhere(
'commitID IN (%Ld)',
mpull($commits, 'getID'));
$commit_data = mpull($commit_data, null, 'getCommitID');
}
foreach ($commits as $commit) {
$data = idx($commit_data, $commit->getID());
if ($data) {
$commit->attachCommitData($data);
$objects[$commit->getPHID()] = $commit;
} else {
// If we couldn't load the commit data, just act as though we
// couldn't load the object at all so we don't load half an object.
}
}
break;
case PhabricatorPHIDConstants::PHID_TYPE_TASK:
$task_dao = new ManiphestTask();
$tasks = $task_dao->loadAllWhere(
'phid IN (%Ls)',
$phids);
foreach ($tasks as $task) {
$objects[$task->getPHID()] = $task;
}
break;
case PhabricatorPHIDConstants::PHID_TYPE_CONF:
$config_dao = new PhabricatorConfigEntry();
$entries = $config_dao->loadAllWhere(
'phid IN (%Ls)',
$phids);
foreach ($entries as $entry) {
$objects[$entry->getPHID()] = $entry;
}
break;
case PhabricatorPHIDConstants::PHID_TYPE_DREV:
$revision_dao = new DifferentialRevision();
$revisions = $revision_dao->loadAllWhere(
'phid IN (%Ls)',
$phids);
foreach ($revisions as $revision) {
$objects[$revision->getPHID()] = $revision;
}
break;
case PhabricatorPHIDConstants::PHID_TYPE_WIKI:
$document_dao = new PhrictionDocument();
$documents = $document_dao->loadAllWhere(
'phid IN (%Ls)',
$phids);
foreach ($documents as $document) {
$objects[$document->getPHID()] = $document;
}
break;
case PhabricatorPHIDConstants::PHID_TYPE_QUES:
$questions = id(new PonderQuestionQuery())
->setViewer($this->viewer)
->withPHIDs($phids)
->execute();
foreach ($questions as $question) {
$objects[$question->getPHID()] = $question;
}
break;
case PhabricatorPHIDConstants::PHID_TYPE_MOCK:
$mocks = id(new PholioMockQuery())
->setViewer($this->viewer)
->withPHIDs($phids)
->execute();
foreach ($mocks as $mock) {
$objects[$mock->getPHID()] = $mock;
}
break;
case PhabricatorPHIDConstants::PHID_TYPE_XACT:
$subtypes = array();
foreach ($phids as $phid) {
$subtypes[phid_get_subtype($phid)][] = $phid;
}
$xactions = array();
foreach ($subtypes as $subtype => $subtype_phids) {
// TODO: Do this magically.
switch ($subtype) {
case PhabricatorPHIDConstants::PHID_TYPE_MOCK:
$results = id(new PholioTransactionQuery())
->setViewer($this->viewer)
->withPHIDs($subtype_phids)
->execute();
$xactions += mpull($results, null, 'getPHID');
break;
case PhabricatorPHIDConstants::PHID_TYPE_MCRO:
$results = id(new PhabricatorMacroTransactionQuery())
->setViewer($this->viewer)
->withPHIDs($subtype_phids)
->execute();
$xactions += mpull($results, null, 'getPHID');
break;
}
}
foreach ($xactions as $xaction) {
$objects[$xaction->getPHID()] = $xaction;
}
break;
case PhabricatorPHIDConstants::PHID_TYPE_MCRO:
$macros = id(new PhabricatorFileImageMacro())->loadAllWhere(
'phid IN (%Ls)',
$phids);
$objects += mpull($macros, null, 'getPHID');
break;
}
} }
return $objects; return $objects;
} }
private function loadObjectsOfType($type, array $phids) {
switch ($type) {
case PhabricatorPHIDConstants::PHID_TYPE_USER:
$user_dao = new PhabricatorUser();
$users = $user_dao->loadAllWhere(
'phid in (%Ls)',
$phids);
return mpull($users, null, 'getPHID');
case PhabricatorPHIDConstants::PHID_TYPE_CMIT:
$commit_dao = new PhabricatorRepositoryCommit();
$commits = $commit_dao->putInSet(new LiskDAOSet())->loadAllWhere(
'phid IN (%Ls)',
$phids);
return mpull($commits, null, 'getPHID');
case PhabricatorPHIDConstants::PHID_TYPE_TASK:
$task_dao = new ManiphestTask();
$tasks = $task_dao->loadAllWhere(
'phid IN (%Ls)',
$phids);
return mpull($tasks, null, 'getPHID');
case PhabricatorPHIDConstants::PHID_TYPE_CONF:
$config_dao = new PhabricatorConfigEntry();
$entries = $config_dao->loadAllWhere(
'phid IN (%Ls)',
$phids);
return mpull($entries, null, 'getPHID');
case PhabricatorPHIDConstants::PHID_TYPE_FILE:
$object = new PhabricatorFile();
$files = $object->loadAllWhere('phid IN (%Ls)', $phids);
return mpull($files, null, 'getPHID');
case PhabricatorPHIDConstants::PHID_TYPE_PROJ:
$object = new PhabricatorProject();
if ($this->viewer) {
$projects = id(new PhabricatorProjectQuery())
->setViewer($this->viewer)
->withPHIDs($phids)
->execute();
} else {
$projects = $object->loadAllWhere('phid IN (%Ls)', $phids);
}
return mpull($projects, null, 'getPHID');
case PhabricatorPHIDConstants::PHID_TYPE_REPO:
$object = new PhabricatorRepository();
$repositories = $object->loadAllWhere('phid in (%Ls)', $phids);
return mpull($repositories, null, 'getPHID');
case PhabricatorPHIDConstants::PHID_TYPE_OPKG:
$object = new PhabricatorOwnersPackage();
$packages = $object->loadAllWhere('phid in (%Ls)', $phids);
return mpull($packages, null, 'getPHID');
case PhabricatorPHIDConstants::PHID_TYPE_APRJ:
$project_dao = new PhabricatorRepositoryArcanistProject();
$projects = $project_dao->loadAllWhere(
'phid IN (%Ls)',
$phids);
return mpull($projects, null, 'getPHID');
case PhabricatorPHIDConstants::PHID_TYPE_MLST:
$object = new PhabricatorMetaMTAMailingList();
$lists = $object->loadAllWhere('phid IN (%Ls)', $phids);
return mpull($lists, null, 'getPHID');
case PhabricatorPHIDConstants::PHID_TYPE_DREV:
$revision_dao = new DifferentialRevision();
$revisions = $revision_dao->loadAllWhere(
'phid IN (%Ls)',
$phids);
return mpull($revisions, null, 'getPHID');
case PhabricatorPHIDConstants::PHID_TYPE_WIKI:
$document_dao = new PhrictionDocument();
$documents = $document_dao->loadAllWhere(
'phid IN (%Ls)',
$phids);
return mpull($documents, null, 'getPHID');
case PhabricatorPHIDConstants::PHID_TYPE_QUES:
$questions = id(new PonderQuestionQuery())
->setViewer($this->viewer)
->withPHIDs($phids)
->execute();
return mpull($questions, null, 'getPHID');
case PhabricatorPHIDConstants::PHID_TYPE_MOCK:
$mocks = id(new PholioMockQuery())
->setViewer($this->viewer)
->withPHIDs($phids)
->execute();
return mpull($mocks, null, 'getPHID');
case PhabricatorPHIDConstants::PHID_TYPE_XACT:
$subtypes = array();
foreach ($phids as $phid) {
$subtypes[phid_get_subtype($phid)][] = $phid;
}
$xactions = array();
foreach ($subtypes as $subtype => $subtype_phids) {
// TODO: Do this magically.
switch ($subtype) {
case PhabricatorPHIDConstants::PHID_TYPE_MOCK:
$results = id(new PholioTransactionQuery())
->setViewer($this->viewer)
->withPHIDs($subtype_phids)
->execute();
$xactions += mpull($results, null, 'getPHID');
break;
case PhabricatorPHIDConstants::PHID_TYPE_MCRO:
$results = id(new PhabricatorMacroTransactionQuery())
->setViewer($this->viewer)
->withPHIDs($subtype_phids)
->execute();
$xactions += mpull($results, null, 'getPHID');
break;
}
}
return mpull($xactions, null, 'getPHID');
case PhabricatorPHIDConstants::PHID_TYPE_MCRO:
$macros = id(new PhabricatorFileImageMacro())->loadAllWhere(
'phid IN (%Ls)',
$phids);
return mpull($macros, null, 'getPHID');
case PhabricatorPHIDConstants::PHID_TYPE_PSTE:
$pastes = id(new PhabricatorPasteQuery())
->withPHIDs($phids)
->setViewer($this->viewer)
->execute();
return mpull($pastes, null, 'getPHID');
case PhabricatorPHIDConstants::PHID_TYPE_BLOG:
$blogs = id(new PhameBlogQuery())
->withPHIDs($phids)
->setViewer($this->viewer)
->execute();
return mpull($blogs, null, 'getPHID');
case PhabricatorPHIDConstants::PHID_TYPE_POST:
$posts = id(new PhamePostQuery())
->withPHIDs($phids)
->setViewer($this->viewer)
->execute();
return mpull($posts, null, 'getPHID');
}
}
public function loadHandles() { public function loadHandles() {
$types = phid_group_by_type($this->phids); $types = phid_group_by_type($this->phids);
@ -172,7 +200,10 @@ final class PhabricatorObjectHandleData {
$external_loaders = PhabricatorEnv::getEnvConfig('phid.external-loaders'); $external_loaders = PhabricatorEnv::getEnvConfig('phid.external-loaders');
foreach ($types as $type => $phids) { foreach ($types as $type => $phids) {
$objects = $this->loadObjectsOfType($type, $phids);
switch ($type) { switch ($type) {
case PhabricatorPHIDConstants::PHID_TYPE_MAGIC: case PhabricatorPHIDConstants::PHID_TYPE_MAGIC:
// Black magic! // Black magic!
foreach ($phids as $phid) { foreach ($phids as $phid) {
@ -197,13 +228,9 @@ final class PhabricatorObjectHandleData {
$handles[$phid] = $handle; $handles[$phid] = $handle;
} }
break; break;
case PhabricatorPHIDConstants::PHID_TYPE_USER: case PhabricatorPHIDConstants::PHID_TYPE_USER:
$object = new PhabricatorUser(); $image_phids = mpull($objects, 'getProfileImagePHID');
$users = $object->loadAllWhere('phid IN (%Ls)', $phids);
$users = mpull($users, null, 'getPHID');
$image_phids = mpull($users, 'getProfileImagePHID');
$image_phids = array_unique(array_filter($image_phids)); $image_phids = array_unique(array_filter($image_phids));
$images = array(); $images = array();
@ -221,10 +248,10 @@ final class PhabricatorObjectHandleData {
$handle = new PhabricatorObjectHandle(); $handle = new PhabricatorObjectHandle();
$handle->setPHID($phid); $handle->setPHID($phid);
$handle->setType($type); $handle->setType($type);
if (empty($users[$phid])) { if (empty($objects[$phid])) {
$handle->setName('Unknown User'); $handle->setName('Unknown User');
} else { } else {
$user = $users[$phid]; $user = $objects[$phid];
$handle->setName($user->getUsername()); $handle->setName($user->getUsername());
$handle->setURI('/p/'.$user->getUsername().'/'); $handle->setURI('/p/'.$user->getUsername().'/');
$handle->setFullName( $handle->setFullName(
@ -251,20 +278,16 @@ final class PhabricatorObjectHandleData {
$handles[$phid] = $handle; $handles[$phid] = $handle;
} }
break; break;
case PhabricatorPHIDConstants::PHID_TYPE_MLST: case PhabricatorPHIDConstants::PHID_TYPE_MLST:
$object = new PhabricatorMetaMTAMailingList();
$lists = $object->loadAllWhere('phid IN (%Ls)', $phids);
$lists = mpull($lists, null, 'getPHID');
foreach ($phids as $phid) { foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle(); $handle = new PhabricatorObjectHandle();
$handle->setPHID($phid); $handle->setPHID($phid);
$handle->setType($type); $handle->setType($type);
if (empty($lists[$phid])) { if (empty($objects[$phid])) {
$handle->setName('Unknown Mailing List'); $handle->setName('Unknown Mailing List');
} else { } else {
$list = $lists[$phid]; $list = $objects[$phid];
$handle->setName($list->getName()); $handle->setName($list->getName());
$handle->setURI($list->getURI()); $handle->setURI($list->getURI());
$handle->setFullName($list->getName()); $handle->setFullName($list->getName());
@ -273,20 +296,16 @@ final class PhabricatorObjectHandleData {
$handles[$phid] = $handle; $handles[$phid] = $handle;
} }
break; break;
case PhabricatorPHIDConstants::PHID_TYPE_DREV: case PhabricatorPHIDConstants::PHID_TYPE_DREV:
$object = new DifferentialRevision();
$revs = $object->loadAllWhere('phid in (%Ls)', $phids);
$revs = mpull($revs, null, 'getPHID');
foreach ($phids as $phid) { foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle(); $handle = new PhabricatorObjectHandle();
$handle->setPHID($phid); $handle->setPHID($phid);
$handle->setType($type); $handle->setType($type);
if (empty($revs[$phid])) { if (empty($objects[$phid])) {
$handle->setName('Unknown Revision'); $handle->setName('Unknown Revision');
} else { } else {
$rev = $revs[$phid]; $rev = $objects[$phid];
$handle->setName($rev->getTitle()); $handle->setName($rev->getTitle());
$handle->setURI('/D'.$rev->getID()); $handle->setURI('/D'.$rev->getID());
$handle->setFullName('D'.$rev->getID().': '.$rev->getTitle()); $handle->setFullName('D'.$rev->getID().': '.$rev->getTitle());
@ -303,36 +322,28 @@ final class PhabricatorObjectHandleData {
$handles[$phid] = $handle; $handles[$phid] = $handle;
} }
break; break;
case PhabricatorPHIDConstants::PHID_TYPE_CMIT: case PhabricatorPHIDConstants::PHID_TYPE_CMIT:
$object = new PhabricatorRepositoryCommit();
$commits = $object->loadAllWhere('phid in (%Ls)', $phids);
$commits = mpull($commits, null, 'getPHID');
$repository_ids = array();
$callsigns = array();
if ($commits) {
$repository_ids = mpull($commits, 'getRepositoryID');
$repositories = id(new PhabricatorRepository())->loadAllWhere(
'id in (%Ld)', array_unique($repository_ids));
$callsigns = mpull($repositories, 'getCallsign');
}
foreach ($phids as $phid) { foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle(); $handle = new PhabricatorObjectHandle();
$handle->setPHID($phid); $handle->setPHID($phid);
$handle->setType($type); $handle->setType($type);
if (empty($commits[$phid]) || $repository = null;
!isset($callsigns[$repository_ids[$phid]])) { if (!empty($objects[$phid])) {
$repository = $objects[$phid]->loadOneRelative(
new PhabricatorRepository(),
'id',
'getRepositoryID');
}
if (!$repository) {
$handle->setName('Unknown Commit'); $handle->setName('Unknown Commit');
} else { } else {
$commit = $commits[$phid]; $commit = $objects[$phid];
$callsign = $callsigns[$repository_ids[$phid]]; $callsign = $repository->getCallsign();
$repository = $repositories[$repository_ids[$phid]];
$commit_identifier = $commit->getCommitIdentifier(); $commit_identifier = $commit->getCommitIdentifier();
// In case where the repository for the commit was deleted, // In case where the repository for the commit was deleted,
// we don't have have info about the repository anymore. // we don't have info about the repository anymore.
if ($repository) { if ($repository) {
$name = $repository->formatCommitName($commit_identifier); $name = $repository->formatCommitName($commit_identifier);
$handle->setName($name); $handle->setName($name);
@ -348,20 +359,16 @@ final class PhabricatorObjectHandleData {
$handles[$phid] = $handle; $handles[$phid] = $handle;
} }
break; break;
case PhabricatorPHIDConstants::PHID_TYPE_TASK: case PhabricatorPHIDConstants::PHID_TYPE_TASK:
$object = new ManiphestTask();
$tasks = $object->loadAllWhere('phid in (%Ls)', $phids);
$tasks = mpull($tasks, null, 'getPHID');
foreach ($phids as $phid) { foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle(); $handle = new PhabricatorObjectHandle();
$handle->setPHID($phid); $handle->setPHID($phid);
$handle->setType($type); $handle->setType($type);
if (empty($tasks[$phid])) { if (empty($objects[$phid])) {
$handle->setName('Unknown Task'); $handle->setName('Unknown Task');
} else { } else {
$task = $tasks[$phid]; $task = $objects[$phid];
$handle->setName($task->getTitle()); $handle->setName($task->getTitle());
$handle->setURI('/T'.$task->getID()); $handle->setURI('/T'.$task->getID());
$handle->setFullName('T'.$task->getID().': '.$task->getTitle()); $handle->setFullName('T'.$task->getID().': '.$task->getTitle());
@ -375,20 +382,16 @@ final class PhabricatorObjectHandleData {
$handles[$phid] = $handle; $handles[$phid] = $handle;
} }
break; break;
case PhabricatorPHIDConstants::PHID_TYPE_CONF: case PhabricatorPHIDConstants::PHID_TYPE_CONF:
$object = new PhabricatorConfigEntry();
$entries = $object->loadAllWhere('phid in (%Ls)', $phids);
$entries = mpull($entries, null, 'getPHID');
foreach ($phids as $phid) { foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle(); $handle = new PhabricatorObjectHandle();
$handle->setPHID($phid); $handle->setPHID($phid);
$handle->setType($type); $handle->setType($type);
if (empty($entries[$phid])) { if (empty($objects[$phid])) {
$handle->setName('Unknown Config Entry'); $handle->setName('Unknown Config Entry');
} else { } else {
$entry = $entries[$phid]; $entry = $objects[$phid];
$handle->setName($entry->getKey()); $handle->setName($entry->getKey());
$handle->setURI('/config/edit/'.$entry->getKey()); $handle->setURI('/config/edit/'.$entry->getKey());
$handle->setFullName($entry->getKey()); $handle->setFullName($entry->getKey());
@ -397,20 +400,16 @@ final class PhabricatorObjectHandleData {
$handles[$phid] = $handle; $handles[$phid] = $handle;
} }
break; break;
case PhabricatorPHIDConstants::PHID_TYPE_FILE: case PhabricatorPHIDConstants::PHID_TYPE_FILE:
$object = new PhabricatorFile();
$files = $object->loadAllWhere('phid IN (%Ls)', $phids);
$files = mpull($files, null, 'getPHID');
foreach ($phids as $phid) { foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle(); $handle = new PhabricatorObjectHandle();
$handle->setPHID($phid); $handle->setPHID($phid);
$handle->setType($type); $handle->setType($type);
if (empty($files[$phid])) { if (empty($objects[$phid])) {
$handle->setName('Unknown File'); $handle->setName('Unknown File');
} else { } else {
$file = $files[$phid]; $file = $objects[$phid];
$handle->setName($file->getName()); $handle->setName($file->getName());
$handle->setURI($file->getBestURI()); $handle->setURI($file->getBestURI());
$handle->setComplete(true); $handle->setComplete(true);
@ -421,28 +420,16 @@ final class PhabricatorObjectHandleData {
$handles[$phid] = $handle; $handles[$phid] = $handle;
} }
break; break;
case PhabricatorPHIDConstants::PHID_TYPE_PROJ: case PhabricatorPHIDConstants::PHID_TYPE_PROJ:
$object = new PhabricatorProject();
if ($this->viewer) {
$projects = id(new PhabricatorProjectQuery())
->setViewer($this->viewer)
->withPHIDs($phids)
->execute();
} else {
$projects = $object->loadAllWhere('phid IN (%Ls)', $phids);
}
$projects = mpull($projects, null, 'getPHID');
foreach ($phids as $phid) { foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle(); $handle = new PhabricatorObjectHandle();
$handle->setPHID($phid); $handle->setPHID($phid);
$handle->setType($type); $handle->setType($type);
if (empty($projects[$phid])) { if (empty($objects[$phid])) {
$handle->setName('Unknown Project'); $handle->setName('Unknown Project');
} else { } else {
$project = $projects[$phid]; $project = $objects[$phid];
$handle->setName($project->getName()); $handle->setName($project->getName());
$handle->setURI('/project/view/'.$project->getID().'/'); $handle->setURI('/project/view/'.$project->getID().'/');
$handle->setComplete(true); $handle->setComplete(true);
@ -450,20 +437,16 @@ final class PhabricatorObjectHandleData {
$handles[$phid] = $handle; $handles[$phid] = $handle;
} }
break; break;
case PhabricatorPHIDConstants::PHID_TYPE_REPO: case PhabricatorPHIDConstants::PHID_TYPE_REPO:
$object = new PhabricatorRepository();
$repositories = $object->loadAllWhere('phid in (%Ls)', $phids);
$repositories = mpull($repositories, null, 'getPHID');
foreach ($phids as $phid) { foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle(); $handle = new PhabricatorObjectHandle();
$handle->setPHID($phid); $handle->setPHID($phid);
$handle->setType($type); $handle->setType($type);
if (empty($repositories[$phid])) { if (empty($objects[$phid])) {
$handle->setName('Unknown Repository'); $handle->setName('Unknown Repository');
} else { } else {
$repository = $repositories[$phid]; $repository = $objects[$phid];
$handle->setName($repository->getCallsign()); $handle->setName($repository->getCallsign());
$handle->setURI('/diffusion/'.$repository->getCallsign().'/'); $handle->setURI('/diffusion/'.$repository->getCallsign().'/');
$handle->setComplete(true); $handle->setComplete(true);
@ -471,20 +454,16 @@ final class PhabricatorObjectHandleData {
$handles[$phid] = $handle; $handles[$phid] = $handle;
} }
break; break;
case PhabricatorPHIDConstants::PHID_TYPE_OPKG: case PhabricatorPHIDConstants::PHID_TYPE_OPKG:
$object = new PhabricatorOwnersPackage();
$packages = $object->loadAllWhere('phid in (%Ls)', $phids);
$packages = mpull($packages, null, 'getPHID');
foreach ($phids as $phid) { foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle(); $handle = new PhabricatorObjectHandle();
$handle->setPHID($phid); $handle->setPHID($phid);
$handle->setType($type); $handle->setType($type);
if (empty($packages[$phid])) { if (empty($objects[$phid])) {
$handle->setName('Unknown Package'); $handle->setName('Unknown Package');
} else { } else {
$package = $packages[$phid]; $package = $objects[$phid];
$handle->setName($package->getName()); $handle->setName($package->getName());
$handle->setURI('/owners/package/'.$package->getID().'/'); $handle->setURI('/owners/package/'.$package->getID().'/');
$handle->setComplete(true); $handle->setComplete(true);
@ -492,27 +471,23 @@ final class PhabricatorObjectHandleData {
$handles[$phid] = $handle; $handles[$phid] = $handle;
} }
break; break;
case PhabricatorPHIDConstants::PHID_TYPE_APRJ:
$project_dao = new PhabricatorRepositoryArcanistProject();
$projects = $project_dao->loadAllWhere( case PhabricatorPHIDConstants::PHID_TYPE_APRJ:
'phid IN (%Ls)',
$phids);
$projects = mpull($projects, null, 'getPHID');
foreach ($phids as $phid) { foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle(); $handle = new PhabricatorObjectHandle();
$handle->setPHID($phid); $handle->setPHID($phid);
$handle->setType($type); $handle->setType($type);
if (empty($projects[$phid])) { if (empty($objects[$phid])) {
$handle->setName('Unknown Arcanist Project'); $handle->setName('Unknown Arcanist Project');
} else { } else {
$project = $projects[$phid]; $project = $objects[$phid];
$handle->setName($project->getName()); $handle->setName($project->getName());
$handle->setComplete(true); $handle->setComplete(true);
} }
$handles[$phid] = $handle; $handles[$phid] = $handle;
} }
break; break;
case PhabricatorPHIDConstants::PHID_TYPE_WIKI: case PhabricatorPHIDConstants::PHID_TYPE_WIKI:
$document_dao = new PhrictionDocument(); $document_dao = new PhrictionDocument();
$content_dao = new PhrictionContent(); $content_dao = new PhrictionContent();
@ -547,21 +522,16 @@ final class PhabricatorObjectHandleData {
$handles[$phid] = $handle; $handles[$phid] = $handle;
} }
break; break;
case PhabricatorPHIDConstants::PHID_TYPE_QUES:
$questions = id(new PonderQuestionQuery())
->setViewer($this->viewer)
->withPHIDs($phids)
->execute();
$questions = mpull($questions, null, 'getPHID');
case PhabricatorPHIDConstants::PHID_TYPE_QUES:
foreach ($phids as $phid) { foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle(); $handle = new PhabricatorObjectHandle();
$handle->setPHID($phid); $handle->setPHID($phid);
$handle->setType($type); $handle->setType($type);
if (empty($questions[$phid])) { if (empty($objects[$phid])) {
$handle->setName('Unknown Ponder Question'); $handle->setName('Unknown Ponder Question');
} else { } else {
$question = $questions[$phid]; $question = $objects[$phid];
$handle->setName(phutil_utf8_shorten($question->getTitle(), 60)); $handle->setName(phutil_utf8_shorten($question->getTitle(), 60));
$handle->setURI(new PhutilURI('/Q' . $question->getID())); $handle->setURI(new PhutilURI('/Q' . $question->getID()));
$handle->setComplete(true); $handle->setComplete(true);
@ -569,21 +539,16 @@ final class PhabricatorObjectHandleData {
$handles[$phid] = $handle; $handles[$phid] = $handle;
} }
break; break;
case PhabricatorPHIDConstants::PHID_TYPE_PSTE:
$pastes = id(new PhabricatorPasteQuery())
->withPHIDs($phids)
->setViewer($this->viewer)
->execute();
$pastes = mpull($pastes, null, 'getPHID');
case PhabricatorPHIDConstants::PHID_TYPE_PSTE:
foreach ($phids as $phid) { foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle(); $handle = new PhabricatorObjectHandle();
$handle->setPHID($phid); $handle->setPHID($phid);
$handle->setType($type); $handle->setType($type);
if (empty($pastes[$phid])) { if (empty($objects[$phid])) {
$handle->setName('Unknown Paste'); $handle->setName('Unknown Paste');
} else { } else {
$paste = $pastes[$phid]; $paste = $objects[$phid];
$handle->setName($paste->getTitle()); $handle->setName($paste->getTitle());
$handle->setFullName($paste->getFullName()); $handle->setFullName($paste->getFullName());
$handle->setURI('/P'.$paste->getID()); $handle->setURI('/P'.$paste->getID());
@ -592,21 +557,16 @@ final class PhabricatorObjectHandleData {
$handles[$phid] = $handle; $handles[$phid] = $handle;
} }
break; break;
case PhabricatorPHIDConstants::PHID_TYPE_BLOG:
$blogs = id(new PhameBlogQuery())
->withPHIDs($phids)
->setViewer($this->viewer)
->execute();
$blogs = mpull($blogs, null, 'getPHID');
case PhabricatorPHIDConstants::PHID_TYPE_BLOG:
foreach ($phids as $phid) { foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle(); $handle = new PhabricatorObjectHandle();
$handle->setPHID($phid); $handle->setPHID($phid);
$handle->setType($type); $handle->setType($type);
if (empty($blogs[$phid])) { if (empty($objects[$phid])) {
$handle->setName('Unknown Blog'); $handle->setName('Unknown Blog');
} else { } else {
$blog = $blogs[$phid]; $blog = $objects[$phid];
$handle->setName($blog->getName()); $handle->setName($blog->getName());
$handle->setFullName($blog->getName()); $handle->setFullName($blog->getName());
$handle->setURI('/phame/blog/view/'.$blog->getID().'/'); $handle->setURI('/phame/blog/view/'.$blog->getID().'/');
@ -615,21 +575,16 @@ final class PhabricatorObjectHandleData {
$handles[$phid] = $handle; $handles[$phid] = $handle;
} }
break; break;
case PhabricatorPHIDConstants::PHID_TYPE_POST:
$posts = id(new PhamePostQuery())
->withPHIDs($phids)
->setViewer($this->viewer)
->execute();
$posts = mpull($posts, null, 'getPHID');
case PhabricatorPHIDConstants::PHID_TYPE_POST:
foreach ($phids as $phid) { foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle(); $handle = new PhabricatorObjectHandle();
$handle->setPHID($phid); $handle->setPHID($phid);
$handle->setType($type); $handle->setType($type);
if (empty($posts[$phid])) { if (empty($objects[$phid])) {
$handle->setName('Unknown Post'); $handle->setName('Unknown Post');
} else { } else {
$post = $posts[$phid]; $post = $objects[$phid];
$handle->setName($post->getTitle()); $handle->setName($post->getTitle());
$handle->setFullName($post->getTitle()); $handle->setFullName($post->getTitle());
$handle->setURI('/phame/post/view/'.$post->getID().'/'); $handle->setURI('/phame/post/view/'.$post->getID().'/');
@ -638,21 +593,16 @@ final class PhabricatorObjectHandleData {
$handles[$phid] = $handle; $handles[$phid] = $handle;
} }
break; break;
case PhabricatorPHIDConstants::PHID_TYPE_MOCK:
$mocks = id(new PholioMockQuery())
->withPHIDs($phids)
->setViewer($this->viewer)
->execute();
$mocks = mpull($mocks, null, 'getPHID');
case PhabricatorPHIDConstants::PHID_TYPE_MOCK:
foreach ($phids as $phid) { foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle(); $handle = new PhabricatorObjectHandle();
$handle->setPHID($phid); $handle->setPHID($phid);
$handle->setType($type); $handle->setType($type);
if (empty($mocks[$phid])) { if (empty($objects[$phid])) {
$handle->setName('Unknown Mock'); $handle->setName('Unknown Mock');
} else { } else {
$mock = $mocks[$phid]; $mock = $objects[$phid];
$handle->setName($mock->getName()); $handle->setName($mock->getName());
$handle->setFullName('M'.$mock->getID().': '.$mock->getName()); $handle->setFullName('M'.$mock->getID().': '.$mock->getName());
$handle->setURI('/M'.$mock->getID()); $handle->setURI('/M'.$mock->getID());
@ -661,19 +611,16 @@ final class PhabricatorObjectHandleData {
$handles[$phid] = $handle; $handles[$phid] = $handle;
} }
break; break;
case PhabricatorPHIDConstants::PHID_TYPE_MCRO: case PhabricatorPHIDConstants::PHID_TYPE_MCRO:
$macros = id(new PhabricatorFileImageMacro())->loadAllWhere(
'phid IN (%Ls)',
$phids);
$macros = mpull($macros, null, 'getPHID');
foreach ($phids as $phid) { foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle(); $handle = new PhabricatorObjectHandle();
$handle->setPHID($phid); $handle->setPHID($phid);
$handle->setType($type); $handle->setType($type);
if (empty($macros[$phid])) { if (empty($objects[$phid])) {
$handle->setName('Unknown Macro'); $handle->setName('Unknown Macro');
} else { } else {
$macro = $macros[$phid]; $macro = $objects[$phid];
$handle->setName($macro->getName()); $handle->setName($macro->getName());
$handle->setFullName('Image Macro "'.$macro->getName().'"'); $handle->setFullName('Image Macro "'.$macro->getName().'"');
$handle->setURI('/macro/view/'.$macro->getID().'/'); $handle->setURI('/macro/view/'.$macro->getID().'/');
@ -682,6 +629,7 @@ final class PhabricatorObjectHandleData {
$handles[$phid] = $handle; $handles[$phid] = $handle;
} }
break; break;
default: default:
$loader = null; $loader = null;
if (isset($external_loaders[$type])) { if (isset($external_loaders[$type])) {
@ -706,6 +654,7 @@ final class PhabricatorObjectHandleData {
$handles[$phid] = $handle; $handles[$phid] = $handle;
} }
break; break;
} }
} }

View file

@ -67,8 +67,6 @@ final class PholioMockViewController extends PholioController {
$output = new PholioMockImagesView(); $output = new PholioMockImagesView();
$output->setMock($mock); $output->setMock($mock);
$carousel = $output->render();
$xaction_view = id(new PhabricatorApplicationTransactionView()) $xaction_view = id(new PhabricatorApplicationTransactionView())
->setUser($this->getRequest()->getUser()) ->setUser($this->getRequest()->getUser())
->setTransactions($xactions) ->setTransactions($xactions)
@ -80,11 +78,12 @@ final class PholioMockViewController extends PholioController {
$header, $header,
$actions, $actions,
$properties, $properties,
$carousel, $output->render(),
$xaction_view, $xaction_view,
$add_comment, $add_comment,
); );
return $this->buildApplicationPage( return $this->buildApplicationPage(
$content, $content,
array( array(

View file

@ -13,22 +13,59 @@ final class PholioMockImagesView extends AphrontView {
throw new Exception("Call setMock() before render()!"); throw new Exception("Call setMock() before render()!");
} }
$mockview = array();
$file = head($this->mock->getImages())->getFile(); $file = head($this->mock->getImages())->getFile();
$image_tag = phutil_tag( $main_image_id = celerity_generate_unique_node_id();
'img',
array(
'src' => $file->getBestURI(),
'class' => 'pholio-mock-image',
),
'');
return phutil_tag( $main_image_tag = phutil_tag(
'img',
array(
'src' => $file->getBestURI(),
'class' => 'pholio-mock-image',
'id' => $main_image_id,
));
$mockview[] = phutil_tag(
'div', 'div',
array( array(
'class' => 'pholio-mock-image-container', 'class' => 'pholio-mock-image-container',
), ),
$image_tag); $main_image_tag);
if (count($this->mock->getImages()) > 1) {
require_celerity_resource('javelin-behavior-pholio-mock-view');
$config = array('mainID' => $main_image_id);
Javelin::initBehavior('pholio-mock-view', $config);
$thumbnails = array();
foreach ($this->mock->getImages() as $image) {
$thumbfile = $image->getFile();
$tag = javelin_tag(
'img',
array(
'src' => $thumbfile->getThumb160x120URI(),
'sigil' => 'mock-thumbnail',
'class' => 'pholio-mock-carousel-thumbnail',
'meta' => array(
'fullSizeURI' => $thumbfile->getBestURI(),
'imageID' => $image->getID(),
),
));
$thumbnails[] = $tag;
}
$mockview[] = phutil_tag(
'div',
array(
'class' => 'pholio-mock-carousel',
),
$thumbnails);
}
return $this->renderHTMLView($mockview);
} }
} }

View file

@ -57,9 +57,10 @@ final class PhabricatorSearchResultView extends AphrontView {
case PhabricatorPHIDConstants::PHID_TYPE_CMIT: case PhabricatorPHIDConstants::PHID_TYPE_CMIT:
$object_name = $handle->getName(); $object_name = $handle->getName();
if ($this->object) { if ($this->object) {
$data = $this->object->getCommitData(); $data = $this->object->loadOneRelative(
$summary = $data->getSummary(); new PhabricatorRepositoryCommitData(),
if (strlen($summary)) { 'commitID');
if ($data && strlen($data->getSummary())) {
$object_name = $handle->getName().': '.$data->getSummary(); $object_name = $handle->getName().': '.$data->getSummary();
} }
} }

View file

@ -14,6 +14,10 @@ final class PhabricatorApplicationSettings extends PhabricatorApplication {
return 'settings'; return 'settings';
} }
public function canUninstall() {
return false;
}
public function getRoutes() { public function getRoutes() {
return array( return array(
'/settings/' => array( '/settings/' => array(

View file

@ -6,6 +6,10 @@ final class PhabricatorApplicationSubscriptions extends PhabricatorApplication {
return false; return false;
} }
public function canUninstall() {
return false;
}
public function getEventListeners() { public function getEventListeners() {
return array( return array(
new PhabricatorSubscriptionsUIEventListener(), new PhabricatorSubscriptionsUIEventListener(),

View file

@ -6,6 +6,10 @@ final class PhabricatorApplicationTransactions extends PhabricatorApplication {
return false; return false;
} }
public function canUninstall() {
return false;
}
public function getRoutes() { public function getRoutes() {
return array( return array(
'/transactions/' => array( '/transactions/' => array(

View file

@ -30,6 +30,9 @@ some subdirectory of an existing website. Navigate to whatever domain you're
going to use and make sure Apache serves you something to verify that DNS going to use and make sure Apache serves you something to verify that DNS
is correctly configured. is correctly configured.
NOTE: The domain must contain a dot ('.'), i.e. not be just a bare name like
'http://example/'. Some web browsers will not set cookies otherwise.
Now, either create a VirtualHost entry (to put Phabricator on a subdomain) Now, either create a VirtualHost entry (to put Phabricator on a subdomain)
or edit the Directory entry for the DocumentRoot. It should look something like or edit the Directory entry for the DocumentRoot. It should look something like
this: this:

View file

@ -176,6 +176,49 @@ final class CeleritySpriteGenerator {
return $sheet; return $sheet;
} }
public function buildConpherenceSheet() {
$icons = $this->getDirectoryList('conpher_1x');
$scales = array(
'1x' => 1,
'2x' => 2,
);
$template = id(new PhutilSprite())
->setSourceSize(32, 32);
$sprites = array();
foreach ($icons as $icon) {
$color = preg_match('/_on/', $icon) ? 'on' : 'off';
$prefix = 'conpher_';
$sprite = id(clone $template)
->setName($prefix.$icon);
$tcss = array();
$tcss[] = '.'.$prefix.$icon;
if ($color == 'on') {
$class = str_replace('_on', '_off', $prefix.$icon);
$tcss[] = '.device-desktop .'.$class.':hover ';
}
$sprite->setTargetCSS(implode(', ', $tcss));
foreach ($scales as $scale_key => $scale) {
$path = $this->getPath($prefix.$scale_key.'/'.$icon.'.png');
$sprite->setSourceFile($path, $scale);
}
$sprites[] = $sprite;
}
$sheet = $this->buildSheet('conpher', true);
$sheet->setScales($scales);
foreach ($sprites as $sprite) {
$sheet->addSprite($sprite);
}
return $sheet;
}
public function buildGradientSheet() { public function buildGradientSheet() {
$gradients = $this->getDirectoryList('gradients'); $gradients = $this->getDirectoryList('gradients');

View file

@ -83,13 +83,25 @@ final class AphrontSideNavFilterView extends AphrontView {
return $this->menu; return $this->menu;
} }
public function addFilter( public function addFilter($key, $name, $uri = null) {
return $this->addThing(
$key, $name, $uri, PhabricatorMenuItemView::TYPE_LINK);
}
public function addButton($key, $name, $uri = null) {
return $this->addThing(
$key, $name, $uri, PhabricatorMenuItemView::TYPE_BUTTON);
}
private function addThing(
$key, $key,
$name, $name,
$uri = null) { $uri = null,
$type) {
$item = id(new PhabricatorMenuItemView()) $item = id(new PhabricatorMenuItemView())
->setName($name); ->setName($name)
->setType($type);
if (strlen($key)) { if (strlen($key)) {
$item->setKey($key); $item->setKey($key);

View file

@ -5,6 +5,7 @@ final class PhabricatorMenuItemView extends AphrontTagView {
const TYPE_LINK = 'type-link'; const TYPE_LINK = 'type-link';
const TYPE_SPACER = 'type-spacer'; const TYPE_SPACER = 'type-spacer';
const TYPE_LABEL = 'type-label'; const TYPE_LABEL = 'type-label';
const TYPE_BUTTON = 'type-button';
private $name; private $name;
private $href; private $href;

View file

@ -25,6 +25,17 @@ final class PhabricatorMenuView extends AphrontTagView {
return $item; return $item;
} }
public function newButton($name, $href) {
$item = id(new PhabricatorMenuItemView())
->setType(PhabricatorMenuItemView::TYPE_BUTTON)
->setName($name)
->setHref($href);
$this->addMenuItem($item);
return $item;
}
public function addMenuItem(PhabricatorMenuItemView $item) { public function addMenuItem(PhabricatorMenuItemView $item) {
$key = $item->getKey(); $key = $item->getKey();
$this->items[] = $item; $this->items[] = $item;

View file

@ -393,6 +393,7 @@ final class PhabricatorMainMenuView extends AphrontView {
'bubbleID' => $bubble_id, 'bubbleID' => $bubble_id,
'countID' => $count_id, 'countID' => $count_id,
'dropdownID' => $dropdown_id, 'dropdownID' => $dropdown_id,
'loadingText' => pht('Loading...'),
)); ));
$notification_dropdown = javelin_tag( $notification_dropdown = javelin_tag(

View file

@ -86,6 +86,10 @@
padding: 15px 20px; padding: 15px 20px;
} }
.device-phone .aphront-panel-preview {
display: none;
}
.aphront-panel-preview-wide { .aphront-panel-preview-wide {
width: 1080px; width: 1080px;
margin-left: auto; margin-left: auto;

View file

@ -83,9 +83,3 @@
.device-desktop .phabricator-side-menu-home .phabricator-nav-content { .device-desktop .phabricator-side-menu-home .phabricator-nav-content {
margin-left: 240px; margin-left: 240px;
} }
/* Chrome annoyingly has a url display over the nav
if the nav is the tallest page (home) */
.phabricator-menu-view {
margin-bottom: 40px;
}

View file

@ -9,6 +9,10 @@
padding: 2px 0px; padding: 2px 0px;
} }
.device-phone .phabricator-transaction-view {
margin: 10px 0;
}
.phabricator-transaction-detail { .phabricator-transaction-detail {
border-color: #dddddd; border-color: #dddddd;
border-width: 1px 10px; border-width: 1px 10px;
@ -18,6 +22,8 @@
.device-phone .phabricator-transaction-detail { .device-phone .phabricator-transaction-detail {
margin: 0; margin: 0;
min-height: 50px;
background: #fff;
} }
.phabricator-transaction-header { .phabricator-transaction-header {
@ -30,9 +36,13 @@
} }
.phabricator-transaction-info { .phabricator-transaction-info {
color: #666666; color: #777;
float: right; float: right;
font-size: 11px; font-size: 11px;
}
.device-phone .phabricator-transaction-info {
display: none;
} }
.phabricator-transaction-content { .phabricator-transaction-content {

View file

@ -42,6 +42,8 @@
.phabricator-main-menu-logo { .phabricator-main-menu-logo {
display: inline-block; display: inline-block;
width: 139px; width: 139px;
height: 44px;
float: left;
margin-right: 6px; margin-right: 6px;
padding-right: 6px; padding-right: 6px;
padding-left: 6px; padding-left: 6px;
@ -152,6 +154,7 @@
} }
.device .phabricator-main-menu-search-container { .device .phabricator-main-menu-search-container {
padding: 0;
margin: 0 18px 0 60px; margin: 0 18px 0 60px;
} }
@ -172,6 +175,12 @@
padding: 6px 32px 6px 10px; padding: 6px 32px 6px 10px;
} }
.device .phabricator-main-menu-search input {
height: 16px;
font-size: 15px;
border-radius: 15px;
}
.phabricator-main-menu-search input:focus { .phabricator-main-menu-search input:focus {
background: #c9c9c9; background: #c9c9c9;
} }
@ -196,6 +205,11 @@
right: 6px; right: 6px;
} }
.device .phabricator-main-menu-search button {
top: 3px;
}
.phabricator-main-menu-search-target div.jx-typeahead-results { .phabricator-main-menu-search-target div.jx-typeahead-results {
border-radius: 4px; border-radius: 4px;
box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.35); box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.35);
@ -253,6 +267,7 @@ a:hover .phabricator-main-search-typeahead-result .result-type {
.phabricator-main-menu-alerts { .phabricator-main-menu-alerts {
display: inline-block; display: inline-block;
border-radius: 15px; border-radius: 15px;
float: left;
background: rgba(0,0,0,.2); background: rgba(0,0,0,.2);
height: 20px; height: 20px;
padding: 3px 10px; padding: 3px 10px;
@ -299,23 +314,16 @@ a:hover .phabricator-main-search-typeahead-result .result-type {
.device .phabricator-dark-menu, .device .phabricator-dark-menu,
.device .phabricator-dark-menu a.phabricator-menu-item-type-link { .device .phabricator-dark-menu a.phabricator-menu-item-type-link {
color: #fff; color: #fff;
}
.device .phabricator-dark-menu .phabricator-menu-item-view {
display: block;
padding: 4px 0;
} }
.device .phabricator-dark-menu .phabricator-menu-item-type-label { .device .phabricator-dark-menu .phabricator-menu-item-type-label {
text-transform: uppercase; text-transform: uppercase;
font-size: 11px; font-size: 12px;
background-color: #151719; background-color: #151719;
padding: 0 0 0 12px; padding: 0 0 0 12px;
height: 24px; height: 25px;
} font-weight: bold;
.device .phabricator-dark-menu .phabricator-menu-item-type-spacer {
display: none;
} }
.device .phabricator-dark-menu .phabricator-menu-item-type-label .device .phabricator-dark-menu .phabricator-menu-item-type-label
@ -329,6 +337,8 @@ a:hover .phabricator-main-search-typeahead-result .result-type {
border-style: solid; border-style: solid;
border-color: #34373b transparent #282c2d; border-color: #34373b transparent #282c2d;
background-image: url(/rsrc/image/texture/dark-menu.png); background-image: url(/rsrc/image/texture/dark-menu.png);
padding: 4px 0;
display: block;
} }
@ -358,15 +368,15 @@ a:hover .phabricator-main-search-typeahead-result .result-type {
padding-top: 44px; padding-top: 44px;
} }
.device .phabricator-core-menu .phabricator-menu-item-type-link { .device .phabricator-dark-menu .phabricator-menu-item-type-link {
font-size: 15px; font-size: 15px;
min-height: 30px; min-height: 30px;
line-height: 28px;
} }
.device .phabricator-core-menu .device .phabricator-core-menu
.phabricator-menu-item-type-link .phabricator-menu-item-name { .phabricator-menu-item-type-link .phabricator-menu-item-name {
margin-left: 40px; margin-left: 40px;
line-height: 28px;
} }
.device-desktop .phabricator-core-menu { .device-desktop .phabricator-core-menu {
@ -428,9 +438,3 @@ a:hover .phabricator-main-search-typeahead-result .result-type {
.phabricator-menu-item-name { .phabricator-menu-item-name {
padding-left: 12px; padding-left: 12px;
} }
.device .phabricator-application-menu-expanded .phabricator-application-menu {
display: block;
padding-top: 44px;
}

View file

@ -9,6 +9,12 @@
overflow-y: auto; overflow-y: auto;
} }
.phabricator-notification-menu-loading {
text-align: center;
padding: 10px 0;
color: #888888;
}
.device-desktop .phabricator-notification-menu { .device-desktop .phabricator-notification-menu {
position: fixed; position: fixed;
width: 360px; width: 360px;

View file

@ -6,7 +6,18 @@
text-align: center; text-align: center;
} }
.pholio-mock-image { .pholio-mock-carousel {
margin: 10px 0px; background-color: #282828;
display: inline-block; text-align: center;
}
.pholio-mock-carousel-thumbnail {
margin-right: 5px;
display: inline-block;
cursor: pointer;
}
.pholio-mock-image {
margin: 10px 0px;
display: inline-block;
} }

View file

@ -25,6 +25,25 @@
background-color: #000; background-color: #000;
} }
.phabricator-dark-menu .phabricator-menu-item-type-button,
.phabricator-side-menu .phabricator-menu-item-type-button {
width: 50%;
padding: 5px 8px;
display: block;
border-radius: 4px;
border: 2px solid #000;
margin: 10px auto;
color: #fff;
font-size: 14px;
text-shadow: 0px 1px 1px #000000;
font-weight: bold;
text-align: center;
}
.phabricator-side-menu .phabricator-menu-item-type-button:hover {
background-image: url(/rsrc/image/texture/dark-menu-hover.png);
}
.device-desktop .phabricator-side-menu a.phabricator-menu-item-type-link:hover { .device-desktop .phabricator-side-menu a.phabricator-menu-item-type-link:hover {
text-decoration: none; text-decoration: none;
} }

View file

@ -0,0 +1,75 @@
/**
* @provides sprite-conpher-css
* @generated
*/
.sprite-conpher {
background-image: url(/rsrc/image/sprite-conpher.png);
background-repeat: no-repeat;
}
@media
only screen and (min-device-pixel-ratio: 1.5),
only screen and (-webkit-min-device-pixel-ratio: 1.5) {
.sprite-conpher {
background-image: url(/rsrc/image/sprite-conpher-X2.png);
background-size: 132px 132px;
}
}
.conpher_calendar_off {
background-position: 0px 0px;
}
.conpher_calendar_on, .device-desktop .conpher_calendar_off:hover {
background-position: -33px 0px;
}
.conpher_conversation_off {
background-position: -66px 0px;
}
.conpher_conversation_on, .device-desktop .conpher_conversation_off:hover {
background-position: -99px 0px;
}
.conpher_files_off {
background-position: 0px -33px;
}
.conpher_files_on, .device-desktop .conpher_files_off:hover {
background-position: -33px -33px;
}
.conpher_list_off {
background-position: -66px -33px;
}
.conpher_list_on, .device-desktop .conpher_list_off:hover {
background-position: -99px -33px;
}
.conpher_more_off {
background-position: 0px -66px;
}
.conpher_more_on, .device-desktop .conpher_more_off:hover {
background-position: -33px -66px;
}
.conpher_people_off {
background-position: -66px -66px;
}
.conpher_people_on, .device-desktop .conpher_people_off:hover {
background-position: 0px -99px;
}
.conpher_settings_off {
background-position: -33px -99px;
}
.conpher_settings_on, .device-desktop .conpher_settings_off:hover {
background-position: -66px -99px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

View file

@ -14,8 +14,17 @@ JX.behavior('aphlict-dropdown', function(config) {
var bubble = JX.$(config.bubbleID); var bubble = JX.$(config.bubbleID);
var visible = false; var visible = false;
var request = null; var request = null;
var dirty = true;
function refresh() { function refresh() {
if (dirty) {
JX.DOM.setContent(dropdown, config.loadingText);
JX.DOM.alterClass(
dropdown,
'phabricator-notification-menu-loading',
true);
}
if (request) { //already fetching if (request) { //already fetching
return; return;
} }
@ -30,6 +39,11 @@ JX.behavior('aphlict-dropdown', function(config) {
} else { } else {
JX.DOM.alterClass(bubble, 'alert-unread', true); JX.DOM.alterClass(bubble, 'alert-unread', true);
} }
dirty = false;
JX.DOM.alterClass(
dropdown,
'phabricator-notification-menu-loading',
false);
JX.DOM.setContent(dropdown, JX.$H(response.content)); JX.DOM.setContent(dropdown, JX.$H(response.content));
request = null; request = null;
}); });
@ -74,7 +88,9 @@ JX.behavior('aphlict-dropdown', function(config) {
if (visible) { if (visible) {
JX.DOM.hide(dropdown); JX.DOM.hide(dropdown);
} else { } else {
refresh(); if (dirty) {
refresh();
}
var p = JX.$V(bubble); var p = JX.$V(bubble);
p.y = null; p.y = null;
@ -88,5 +104,8 @@ JX.behavior('aphlict-dropdown', function(config) {
} }
) )
JX.Stratcom.listen('notification-panel-update', null, refresh); JX.Stratcom.listen('notification-panel-update', null, function() {
dirty = true;
refresh();
});
}); });

View file

@ -14,6 +14,39 @@ JX.behavior('aphront-form-disable-on-submit', function(config) {
new_tab = (raw.altKey || raw.ctrlKey || raw.metaKey || raw.shiftKey); new_tab = (raw.altKey || raw.ctrlKey || raw.metaKey || raw.shiftKey);
}); });
JX.Stratcom.listen('keypress', ['tag:form', 'tag:textarea'], function(e) {
var raw = e.getRawEvent();
if (e.getSpecialKey() != 'return' || !raw.ctrlKey) {
return;
}
e.kill();
var form = e.getNode('tag:form');
// This allows 'workflow' and similar actions to take effect.
var r = JX.DOM.invoke(form, 'didSyntheticSubmit');
if (r.getPrevented()) {
return;
}
// If nothing handled the synthetic submit, submit normally.
form.submit();
});
function will_submit(root) {
root._disabled = true;
var buttons = JX.DOM.scry(root, 'button');
for (var ii = 0; ii < buttons.length; ii++) {
if (!buttons[ii].disabled) {
buttons[ii].disabled = 'disabled';
JX.DOM.alterClass(buttons[ii], 'disabled', true);
restore.push(buttons[ii]);
}
}
}
JX.Stratcom.listen('submit', 'tag:form', function(e) { JX.Stratcom.listen('submit', 'tag:form', function(e) {
if (e.getNode('workflow')) { if (e.getNode('workflow')) {
// Don't activate for forms with workflow, the workflow behavior will // Don't activate for forms with workflow, the workflow behavior will
@ -40,15 +73,8 @@ JX.behavior('aphront-form-disable-on-submit', function(config) {
if (root._disabled) { if (root._disabled) {
e.kill(); e.kill();
} }
root._disabled = true;
var buttons = JX.DOM.scry(root, 'button'); will_submit(root);
for (var ii = 0; ii < buttons.length; ii++) {
if (!buttons[ii].disabled) {
buttons[ii].disabled = 'disabled';
JX.DOM.alterClass(buttons[ii], 'disabled', true);
restore.push(buttons[ii]);
}
}
}); });
JX.Stratcom.listen('unload', null, function(e) { JX.Stratcom.listen('unload', null, function(e) {

View file

@ -7,8 +7,10 @@
*/ */
JX.behavior('workflow', function() { JX.behavior('workflow', function() {
// Listen for both real
JX.Stratcom.listen( JX.Stratcom.listen(
'submit', ['submit', 'didSyntheticSubmit'],
['workflow', 'tag:form'], ['workflow', 'tag:form'],
function(e) { function(e) {
if (JX.Stratcom.pass()) { if (JX.Stratcom.pass()) {
@ -18,6 +20,7 @@ JX.behavior('workflow', function() {
e.prevent(); e.prevent();
JX.Workflow.newFromForm(target).start(); JX.Workflow.newFromForm(target).start();
}); });
JX.Stratcom.listen( JX.Stratcom.listen(
'click', 'click',
['workflow', 'tag:a'], ['workflow', 'tag:a'],
@ -40,4 +43,5 @@ JX.behavior('workflow', function() {
e.prevent(); e.prevent();
JX.Workflow.newFromLink(target).start(); JX.Workflow.newFromLink(target).start();
}); });
}); });

View file

@ -119,7 +119,11 @@ JX.install('DifferentialInlineCommentEditor', {
JX.DOM.alterClass(drawn[0], 'differential-inline-loading', true); JX.DOM.alterClass(drawn[0], 'differential-inline-loading', true);
}); });
JX.DOM.listen(drawn[0], 'submit', 'inline-edit-form', onsubmit); JX.DOM.listen(
drawn[0],
['submit', 'didSyntheticSubmit'],
'inline-edit-form',
onsubmit);
}, },
_didCompleteWorkflow : function(response) { _didCompleteWorkflow : function(response) {
var op = this.getOperation(); var op = this.getOperation();

View file

@ -0,0 +1,17 @@
/**
* @provides javelin-behavior-pholio-mock-view
* @requires javelin-behavior
* javelin-stratcom
*/
JX.behavior('pholio-mock-view', function(config) {
JX.Stratcom.listen(
'click', // Listen for clicks...
'mock-thumbnail', // ...on nodes with sigil "mock-thumbnail".
function(e) {
var data = e.getNodeData('mock-thumbnail');
var main = JX.$(config.mainID);
main.src = data.fullSizeURI;
});
});

View file

@ -75,21 +75,24 @@ JX.behavior('phabricator-transaction-list', function(config) {
e.kill(); e.kill();
}); });
JX.Stratcom.listen('submit', 'transaction-append', function(e) { JX.Stratcom.listen(
var form = e.getTarget(); ['submit', 'didSyntheticSubmit'],
'transaction-append',
function(e) {
var form = e.getTarget();
JX.Workflow.newFromForm(form, {anchor: next_anchor}) JX.Workflow.newFromForm(form, {anchor: next_anchor})
.setHandler(function(response) { .setHandler(function(response) {
ontransactions(response); ontransactions(response);
var e = JX.DOM.invoke(form, 'willClear'); var e = JX.DOM.invoke(form, 'willClear');
if (!e.getPrevented()) { if (!e.getPrevented()) {
form.reset(); form.reset();
} }
}) })
.start(); .start();
e.kill(); e.kill();
}); });
}); });