diff --git a/resources/celerity/map.php b/resources/celerity/map.php index c8cf00b60f..2e692ac95c 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -1,2279 +1,2274 @@ <?php /** * This file is automatically generated. Use 'bin/celerity map' to rebuild it. * @generated */ return array( 'names' => array( - 'core.pkg.css' => '59ea1706', - 'core.pkg.js' => 'b2ed04a2', + 'core.pkg.css' => 'e62084f9', + 'core.pkg.js' => 'ab0d6d3d', 'darkconsole.pkg.js' => 'ca8671ce', 'differential.pkg.css' => '382ca868', - 'differential.pkg.js' => '36bec171', + 'differential.pkg.js' => '68d225fb', 'diffusion.pkg.css' => '3783278d', 'diffusion.pkg.js' => '077e3ad0', 'javelin.pkg.js' => 'b4831ebf', 'maniphest.pkg.css' => 'f1887d71', 'maniphest.pkg.js' => '2fe8af22', 'rsrc/css/aphront/aphront-bars.css' => '231ac33c', 'rsrc/css/aphront/context-bar.css' => '1c3b0529', 'rsrc/css/aphront/dark-console.css' => '6378ef3d', 'rsrc/css/aphront/dialog-view.css' => 'c01d24b4', 'rsrc/css/aphront/error-view.css' => '9f1d5518', 'rsrc/css/aphront/lightbox-attachment.css' => '7acac05d', 'rsrc/css/aphront/list-filter-view.css' => '2ae43867', 'rsrc/css/aphront/multi-column.css' => '1b95ab2e', 'rsrc/css/aphront/notification.css' => 'ef2c9b34', 'rsrc/css/aphront/pager-view.css' => '2e3539af', 'rsrc/css/aphront/panel-view.css' => '5846dfa2', 'rsrc/css/aphront/phabricator-nav-view.css' => '80e60fc1', 'rsrc/css/aphront/request-failure-view.css' => 'da14df31', 'rsrc/css/aphront/table-view.css' => '88e80148', 'rsrc/css/aphront/tokenizer.css' => '36903077', 'rsrc/css/aphront/tooltip.css' => '9c90229d', 'rsrc/css/aphront/transaction.css' => 'ce491938', 'rsrc/css/aphront/two-column.css' => '16ab3ad2', - 'rsrc/css/aphront/typeahead.css' => '466ac215', + 'rsrc/css/aphront/typeahead.css' => '1f4c9e23', 'rsrc/css/application/auth/auth.css' => '1e655982', 'rsrc/css/application/base/main-menu-view.css' => '0207239c', 'rsrc/css/application/base/notification-menu.css' => '99ffef72', 'rsrc/css/application/base/phabricator-application-launch-view.css' => 'd290ba21', 'rsrc/css/application/base/standard-page-view.css' => '517cdfb1', 'rsrc/css/application/chatlog/chatlog.css' => '852140ff', 'rsrc/css/application/config/config-options.css' => '7fedf08b', 'rsrc/css/application/config/config-template.css' => '25d446d6', 'rsrc/css/application/config/setup-issue.css' => '69e640e7', 'rsrc/css/application/conpherence/menu.css' => '561348ac', 'rsrc/css/application/conpherence/message-pane.css' => 'e46b612c', 'rsrc/css/application/conpherence/notification.css' => '403cf598', 'rsrc/css/application/conpherence/update.css' => '1099a660', 'rsrc/css/application/conpherence/widget-pane.css' => 'bf275a6c', 'rsrc/css/application/contentsource/content-source-view.css' => '4b8b05d4', 'rsrc/css/application/countdown/timer.css' => '86b7b0a0', 'rsrc/css/application/dashboard/dashboard.css' => '2b41640b', 'rsrc/css/application/diff/inline-comment-summary.css' => '8cfd34e8', 'rsrc/css/application/differential/add-comment.css' => 'c478bcaa', 'rsrc/css/application/differential/changeset-view.css' => 'c45747f0', 'rsrc/css/application/differential/core.css' => '7ac3cabc', 'rsrc/css/application/differential/results-table.css' => '239924f9', 'rsrc/css/application/differential/revision-comment.css' => '48186045', 'rsrc/css/application/differential/revision-history.css' => '0e8eb855', 'rsrc/css/application/differential/revision-list.css' => 'f3c47d33', 'rsrc/css/application/differential/table-of-contents.css' => '6bf8e1d2', 'rsrc/css/application/diffusion/commit-view.css' => '92d1e8f9', 'rsrc/css/application/diffusion/diffusion-icons.css' => '384a0f7d', 'rsrc/css/application/diffusion/diffusion-source.css' => '66fdf661', 'rsrc/css/application/directory/phabricator-jump-nav.css' => 'f0c5e726', 'rsrc/css/application/feed/feed.css' => '0d17c209', 'rsrc/css/application/files/global-drag-and-drop.css' => '697324ad', 'rsrc/css/application/flag/flag.css' => '5337623f', 'rsrc/css/application/harbormaster/harbormaster.css' => 'cec833b7', 'rsrc/css/application/herald/herald-test.css' => '778b008e', 'rsrc/css/application/herald/herald.css' => 'c544dd1c', 'rsrc/css/application/maniphest/batch-editor.css' => '8f380ebc', 'rsrc/css/application/maniphest/report.css' => '6fc16517', 'rsrc/css/application/maniphest/task-edit.css' => '8e23031b', 'rsrc/css/application/maniphest/task-summary.css' => '6df1a768', 'rsrc/css/application/objectselector/object-selector.css' => '029a133d', 'rsrc/css/application/owners/owners-path-editor.css' => '2f00933b', 'rsrc/css/application/paste/paste.css' => 'aa1767d1', 'rsrc/css/application/people/people-profile.css' => 'ba7b2762', 'rsrc/css/application/phame/phame.css' => '19ecc703', 'rsrc/css/application/pholio/pholio-edit.css' => 'b9e59b6d', 'rsrc/css/application/pholio/pholio-inline-comments.css' => '52be33f0', 'rsrc/css/application/pholio/pholio.css' => 'e059f955', 'rsrc/css/application/phortune/phortune-credit-card-form.css' => 'b25b4beb', 'rsrc/css/application/phrequent/phrequent.css' => 'ffc185ad', 'rsrc/css/application/phriction/phriction-document-css.css' => '7d7f0071', 'rsrc/css/application/policy/policy-edit.css' => '05cca26a', 'rsrc/css/application/policy/policy-transaction-detail.css' => '82100a43', 'rsrc/css/application/policy/policy.css' => '957ea14c', 'rsrc/css/application/ponder/comments.css' => '6cdccea7', 'rsrc/css/application/ponder/feed.css' => 'e62615b6', 'rsrc/css/application/ponder/post.css' => 'ebab8a70', 'rsrc/css/application/ponder/vote.css' => '8ed6ed8b', 'rsrc/css/application/profile/profile-view.css' => '33e6f703', 'rsrc/css/application/projects/project-tag.css' => '095c9404', 'rsrc/css/application/releeph/releeph-core.css' => '9b3c5733', 'rsrc/css/application/releeph/releeph-preview-branch.css' => 'b7a6f4a5', 'rsrc/css/application/releeph/releeph-request-differential-create-dialog.css' => '8d8b92cd', 'rsrc/css/application/releeph/releeph-request-typeahead.css' => '667a48ae', 'rsrc/css/application/search/search-results.css' => 'f240504c', 'rsrc/css/application/settings/settings.css' => 'ea8f5915', 'rsrc/css/application/slowvote/slowvote.css' => '266df6a1', 'rsrc/css/application/subscriptions/subscribers-list.css' => '5bb30c78', 'rsrc/css/application/tokens/tokens.css' => '3d0f239e', 'rsrc/css/application/uiexample/example.css' => '528b19de', 'rsrc/css/core/core.css' => '40151074', 'rsrc/css/core/remarkup.css' => '80c3a48c', 'rsrc/css/core/syntax.css' => '3c18c1cb', 'rsrc/css/core/z-index.css' => 'efb673ac', 'rsrc/css/diviner/diviner-shared.css' => '38813222', 'rsrc/css/font/font-awesome.css' => '73d075c3', 'rsrc/css/font/font-source-sans-pro.css' => '91d53463', 'rsrc/css/font/phui-font-icon-base.css' => '74cfb6a9', 'rsrc/css/layout/phabricator-action-header-view.css' => 'c14dfc57', 'rsrc/css/layout/phabricator-action-list-view.css' => 'dcd9875f', 'rsrc/css/layout/phabricator-crumbs-view.css' => '6a23399c', 'rsrc/css/layout/phabricator-filetree-view.css' => 'a8c86ace', 'rsrc/css/layout/phabricator-hovercard-view.css' => '46a13cf0', 'rsrc/css/layout/phabricator-side-menu-view.css' => '503699d0', 'rsrc/css/layout/phabricator-source-code-view.css' => '62a99814', 'rsrc/css/phui/calendar/phui-calendar-day.css' => 'de035c8a', 'rsrc/css/phui/calendar/phui-calendar-list.css' => 'c1d0ca59', 'rsrc/css/phui/calendar/phui-calendar-month.css' => 'a92e47d2', 'rsrc/css/phui/calendar/phui-calendar.css' => '5e1ad989', 'rsrc/css/phui/phui-box.css' => '7b3a2eed', 'rsrc/css/phui/phui-button.css' => '3dbdbf0d', 'rsrc/css/phui/phui-document.css' => '3b078dc0', 'rsrc/css/phui/phui-feed-story.css' => '3a59c2cf', 'rsrc/css/phui/phui-fontkit.css' => 'de84aa4a', 'rsrc/css/phui/phui-form-view.css' => '867463b4', 'rsrc/css/phui/phui-form.css' => 'b78ec020', - 'rsrc/css/phui/phui-header-view.css' => '5d245c9c', - 'rsrc/css/phui/phui-icon.css' => '00abbd26', + 'rsrc/css/phui/phui-header-view.css' => '689dbc38', + 'rsrc/css/phui/phui-icon.css' => 'ef701b9b', 'rsrc/css/phui/phui-info-panel.css' => '27ea50a1', 'rsrc/css/phui/phui-list.css' => '65eab261', 'rsrc/css/phui/phui-object-box.css' => 'ce92d8ec', 'rsrc/css/phui/phui-object-item-list-view.css' => '64b6b266', 'rsrc/css/phui/phui-pinboard-view.css' => '874c22f9', - 'rsrc/css/phui/phui-property-list-view.css' => 'af4b381f', + 'rsrc/css/phui/phui-property-list-view.css' => 'c7cbe471', 'rsrc/css/phui/phui-remarkup-preview.css' => '19ad512b', 'rsrc/css/phui/phui-spacing.css' => '042804d6', 'rsrc/css/phui/phui-status.css' => '2f562399', 'rsrc/css/phui/phui-tag-view.css' => '5d09d99e', 'rsrc/css/phui/phui-text.css' => '23e9b4b7', 'rsrc/css/phui/phui-timeline-view.css' => '15ff2a9f', 'rsrc/css/phui/phui-workboard-view.css' => '2bf82d00', 'rsrc/css/phui/phui-workpanel-view.css' => 'fddd97bf', 'rsrc/css/sprite-actions.css' => '969ad0e5', 'rsrc/css/sprite-apps-large.css' => 'd7ef733e', 'rsrc/css/sprite-apps-xlarge.css' => 'db66c878', 'rsrc/css/sprite-apps.css' => 'a0f5d4af', 'rsrc/css/sprite-buttonbar.css' => 'ba1c5738', 'rsrc/css/sprite-conpherence.css' => '3b4a0487', 'rsrc/css/sprite-docs.css' => '5f65d0da', 'rsrc/css/sprite-gradient.css' => 'a10def53', 'rsrc/css/sprite-login.css' => '8d10fb28', 'rsrc/css/sprite-main-header.css' => '92720ee2', 'rsrc/css/sprite-menu.css' => '8da53882', 'rsrc/css/sprite-minicons.css' => 'df4f76fe', 'rsrc/css/sprite-payments.css' => 'cc085d44', 'rsrc/css/sprite-projects.css' => '7578fa56', 'rsrc/css/sprite-remarkup.css' => '5c396a57', - 'rsrc/css/sprite-status.css' => '25d7f92f', 'rsrc/css/sprite-tokens.css' => '1706b943', 'rsrc/externals/font/fontawesome/fontawesome-webfont.eot' => '1cab0752', 'rsrc/externals/font/fontawesome/fontawesome-webfont.ttf' => '2ff84fd2', 'rsrc/externals/font/fontawesome/fontawesome-webfont.woff' => 'a119ee5e', 'rsrc/externals/font/sourcesans/SourceSansPro.woff' => '3614608c', 'rsrc/externals/font/sourcesans/SourceSansProBold.woff' => 'cbf46566', 'rsrc/externals/javelin/core/Event.js' => '69815cac', 'rsrc/externals/javelin/core/Stratcom.js' => 'c293f7b9', 'rsrc/externals/javelin/core/__tests__/event-stop-and-kill.js' => '717554e4', 'rsrc/externals/javelin/core/__tests__/install.js' => 'c432ee85', 'rsrc/externals/javelin/core/__tests__/stratcom.js' => 'da194d4b', 'rsrc/externals/javelin/core/__tests__/util.js' => 'd3b157a9', 'rsrc/externals/javelin/core/init.js' => 'b88ab49e', 'rsrc/externals/javelin/core/init_node.js' => 'd7dde471', 'rsrc/externals/javelin/core/install.js' => '52a92793', 'rsrc/externals/javelin/core/util.js' => '65b0b249', 'rsrc/externals/javelin/docs/Base.js' => '897bb199', 'rsrc/externals/javelin/docs/onload.js' => '81fb4862', 'rsrc/externals/javelin/ext/fx/Color.js' => '7e41274a', 'rsrc/externals/javelin/ext/fx/FX.js' => '54b612ba', 'rsrc/externals/javelin/ext/reactor/core/DynVal.js' => 'f6555212', 'rsrc/externals/javelin/ext/reactor/core/Reactor.js' => '77b1cf6f', 'rsrc/externals/javelin/ext/reactor/core/ReactorNode.js' => 'b4c30592', 'rsrc/externals/javelin/ext/reactor/core/ReactorNodeCalmer.js' => '76f4ebed', 'rsrc/externals/javelin/ext/reactor/dom/RDOM.js' => 'b6d401d6', 'rsrc/externals/javelin/ext/view/HTMLView.js' => 'e5b406f9', 'rsrc/externals/javelin/ext/view/View.js' => '0f764c35', 'rsrc/externals/javelin/ext/view/ViewInterpreter.js' => '0c33c1a0', 'rsrc/externals/javelin/ext/view/ViewPlaceholder.js' => '2fa810fc', 'rsrc/externals/javelin/ext/view/ViewRenderer.js' => '6c2b09a2', 'rsrc/externals/javelin/ext/view/ViewVisitor.js' => 'efe49472', 'rsrc/externals/javelin/ext/view/__tests__/HTMLView.js' => 'f92d7bcb', 'rsrc/externals/javelin/ext/view/__tests__/View.js' => 'bda69c40', 'rsrc/externals/javelin/ext/view/__tests__/ViewInterpreter.js' => '7a94d6a5', 'rsrc/externals/javelin/ext/view/__tests__/ViewRenderer.js' => '5426001c', 'rsrc/externals/javelin/lib/Cookie.js' => '6b3dcf44', 'rsrc/externals/javelin/lib/DOM.js' => '07d99a3d', 'rsrc/externals/javelin/lib/History.js' => 'c60f4327', 'rsrc/externals/javelin/lib/JSON.js' => '08e56a4e', 'rsrc/externals/javelin/lib/Mask.js' => 'b9f26029', 'rsrc/externals/javelin/lib/Request.js' => '7bad574b', 'rsrc/externals/javelin/lib/Resource.js' => '356de121', 'rsrc/externals/javelin/lib/Routable.js' => 'b3e7d692', 'rsrc/externals/javelin/lib/Router.js' => '29274e2b', 'rsrc/externals/javelin/lib/URI.js' => 'd9a9b862', 'rsrc/externals/javelin/lib/Vector.js' => 'bd0aedcd', 'rsrc/externals/javelin/lib/Workflow.js' => '09b15cf1', 'rsrc/externals/javelin/lib/__tests__/Cookie.js' => '5ed109e8', 'rsrc/externals/javelin/lib/__tests__/DOM.js' => 'c984504b', 'rsrc/externals/javelin/lib/__tests__/JSON.js' => '2295d074', 'rsrc/externals/javelin/lib/__tests__/URI.js' => '003ed329', 'rsrc/externals/javelin/lib/__tests__/behavior.js' => '1ea62783', 'rsrc/externals/javelin/lib/behavior.js' => '8a3ed18b', 'rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js' => 'e7c21fb3', 'rsrc/externals/javelin/lib/control/typeahead/Typeahead.js' => 'c54eeefb', 'rsrc/externals/javelin/lib/control/typeahead/normalizer/TypeaheadNormalizer.js' => '5f850b5c', 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadCompositeSource.js' => '84f34ab1', 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadOnDemandSource.js' => 'a79b75a4', 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadPreloadedSource.js' => '66815d9c', 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadSource.js' => '62e18640', 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadStaticSource.js' => 'cdde23f1', 'rsrc/externals/raphael/g.raphael.js' => '40dde778', 'rsrc/externals/raphael/g.raphael.line.js' => '40da039e', 'rsrc/externals/raphael/raphael.js' => '51ee6b43', 'rsrc/image/BFCFDA.png' => 'd5ec91f4', 'rsrc/image/actions/edit.png' => '2fc41442', 'rsrc/image/apple-touch-icon.png' => '8458dda7', 'rsrc/image/avatar.png' => '3eb28cd9', 'rsrc/image/checker_dark.png' => 'd8e65881', 'rsrc/image/checker_light.png' => 'a0155918', 'rsrc/image/credit_cards.png' => '72b8ede8', 'rsrc/image/darkload.gif' => '1ffd3ec6', 'rsrc/image/divot.png' => '94dded62', 'rsrc/image/grippy_texture.png' => 'aca81e2f', 'rsrc/image/icon/fatcow/arrow_branch.png' => '2537c01c', 'rsrc/image/icon/fatcow/arrow_merge.png' => '21b660e0', 'rsrc/image/icon/fatcow/bullet_black.png' => 'ff190031', 'rsrc/image/icon/fatcow/bullet_orange.png' => 'e273e5bb', 'rsrc/image/icon/fatcow/bullet_red.png' => 'c0b75434', 'rsrc/image/icon/fatcow/calendar_edit.png' => '24632275', 'rsrc/image/icon/fatcow/document_black.png' => '45fe1c60', 'rsrc/image/icon/fatcow/flag_blue.png' => 'a01abb1d', 'rsrc/image/icon/fatcow/flag_finish.png' => '67825cee', 'rsrc/image/icon/fatcow/flag_ghost.png' => '20ca8783', 'rsrc/image/icon/fatcow/flag_green.png' => '7e0eaa7a', 'rsrc/image/icon/fatcow/flag_orange.png' => '9e73df66', 'rsrc/image/icon/fatcow/flag_pink.png' => '7e92f3b2', 'rsrc/image/icon/fatcow/flag_purple.png' => 'cc517522', 'rsrc/image/icon/fatcow/flag_red.png' => '04ec726f', 'rsrc/image/icon/fatcow/flag_yellow.png' => '73946fd4', 'rsrc/image/icon/fatcow/folder.png' => '95a435af', 'rsrc/image/icon/fatcow/folder_go.png' => '001cbc94', 'rsrc/image/icon/fatcow/key_question.png' => '52a0c26a', 'rsrc/image/icon/fatcow/link.png' => '7afd4d5e', 'rsrc/image/icon/fatcow/page_white_edit.png' => '39a2eed8', 'rsrc/image/icon/fatcow/page_white_link.png' => 'a90023c7', 'rsrc/image/icon/fatcow/page_white_put.png' => '08c95a0c', 'rsrc/image/icon/fatcow/page_white_text.png' => '1e1f79c3', 'rsrc/image/icon/fatcow/source/conduit.png' => '4ea01d2f', 'rsrc/image/icon/fatcow/source/email.png' => '9bab3239', 'rsrc/image/icon/fatcow/source/fax.png' => '04195e68', 'rsrc/image/icon/fatcow/source/mobile.png' => 'f1321264', 'rsrc/image/icon/fatcow/source/tablet.png' => '49396799', 'rsrc/image/icon/fatcow/source/web.png' => '136ccb5d', 'rsrc/image/icon/fatcow/thumbnails/default160x120.png' => 'f2e8a2eb', 'rsrc/image/icon/fatcow/thumbnails/default60x45.png' => '0118abed', 'rsrc/image/icon/fatcow/thumbnails/image160x120.png' => '79bb556a', 'rsrc/image/icon/fatcow/thumbnails/image60x45.png' => 'c5e1685e', 'rsrc/image/icon/fatcow/thumbnails/pdf160x120.png' => 'ac9edbf5', 'rsrc/image/icon/fatcow/thumbnails/pdf60x45.png' => 'c0db4143', 'rsrc/image/icon/fatcow/thumbnails/zip160x120.png' => '75f9cd0f', 'rsrc/image/icon/fatcow/thumbnails/zip60x45.png' => 'af11bf3e', 'rsrc/image/icon/lightbox/close-2.png' => 'cc40e7c8', 'rsrc/image/icon/lightbox/close-hover-2.png' => 'fb5d6d9e', 'rsrc/image/icon/lightbox/left-arrow-2.png' => '8426133b', 'rsrc/image/icon/lightbox/left-arrow-hover-2.png' => '701e5ee3', 'rsrc/image/icon/lightbox/right-arrow-2.png' => '6d5519a0', 'rsrc/image/icon/lightbox/right-arrow-hover-2.png' => '3a04aa21', 'rsrc/image/icon/subscribe.png' => 'd03ed5a5', 'rsrc/image/icon/tango/attachment.png' => 'ecc8022e', 'rsrc/image/icon/tango/edit.png' => '929a1363', 'rsrc/image/icon/tango/go-down.png' => '96d95e43', 'rsrc/image/icon/tango/log.png' => 'b08cc63a', 'rsrc/image/icon/tango/upload.png' => '7bbb7984', 'rsrc/image/icon/unsubscribe.png' => '25725013', 'rsrc/image/lightblue-header.png' => '5c168b6d', 'rsrc/image/loading.gif' => '75d384cc', 'rsrc/image/loading/boating_24.gif' => '5c90f086', 'rsrc/image/loading/compass_24.gif' => 'b36b4f46', 'rsrc/image/loading/loading_24.gif' => '26bc9adc', 'rsrc/image/loading/loading_48.gif' => '6a4994c7', 'rsrc/image/loading/loading_d48.gif' => 'cdcbe900', 'rsrc/image/loading/loading_w24.gif' => '7662fa2b', 'rsrc/image/main_texture.png' => '29a2c5ad', 'rsrc/image/menu_texture.png' => '5a17580d', 'rsrc/image/people/harding.png' => '45aa614e', 'rsrc/image/people/jefferson.png' => 'afca0e53', 'rsrc/image/people/lincoln.png' => '9369126d', 'rsrc/image/people/mckinley.png' => 'fb8f16ce', 'rsrc/image/people/taft.png' => 'd7bc402c', 'rsrc/image/people/washington.png' => '40dd301c', 'rsrc/image/phrequent_active.png' => 'a466a8ed', 'rsrc/image/phrequent_inactive.png' => 'bfc15a69', 'rsrc/image/search-white.png' => '64cc0d45', 'rsrc/image/search.png' => '82625a7e', 'rsrc/image/sprite-actions-X2.png' => '7dfd5652', 'rsrc/image/sprite-actions.png' => '2ddd18c3', 'rsrc/image/sprite-apps-X2.png' => 'db9e0970', 'rsrc/image/sprite-apps-large-X2.png' => '0e4fa89b', 'rsrc/image/sprite-apps-large.png' => 'f31388f8', 'rsrc/image/sprite-apps-xlarge.png' => 'a751a580', 'rsrc/image/sprite-apps.png' => 'b46a87ae', 'rsrc/image/sprite-buttonbar-X2.png' => '2c09a184', 'rsrc/image/sprite-buttonbar.png' => 'e98e96af', 'rsrc/image/sprite-conpherence-X2.png' => 'cd2d08d7', 'rsrc/image/sprite-conpherence.png' => 'a5ab2eb7', 'rsrc/image/sprite-docs-X2.png' => '6dc1adad', 'rsrc/image/sprite-docs.png' => '4636297f', 'rsrc/image/sprite-gradient.png' => '4ece0b62', 'rsrc/image/sprite-login-X2.png' => 'bf5ceccc', 'rsrc/image/sprite-login.png' => 'c1e200b3', 'rsrc/image/sprite-main-header.png' => '83521873', 'rsrc/image/sprite-menu-X2.png' => '949974c6', 'rsrc/image/sprite-menu.png' => '307d5da0', 'rsrc/image/sprite-minicons-X2.png' => '55377e4e', 'rsrc/image/sprite-minicons.png' => '272644ea', 'rsrc/image/sprite-payments.png' => 'd8576309', 'rsrc/image/sprite-projects-X2.png' => '218fdc8b', 'rsrc/image/sprite-projects.png' => '631ff9a7', 'rsrc/image/sprite-remarkup-X2.png' => '7ee1dc28', 'rsrc/image/sprite-remarkup.png' => 'b4421f07', - 'rsrc/image/sprite-status-X2.png' => '6cb4b401', - 'rsrc/image/sprite-status.png' => '97eb1562', 'rsrc/image/sprite-tokens-X2.png' => 'b4776580', 'rsrc/image/sprite-tokens.png' => '25b75533', 'rsrc/image/texture/card-gradient.png' => '815f26e8', 'rsrc/image/texture/dark-menu-hover.png' => '5fa7ece8', 'rsrc/image/texture/dark-menu.png' => '7e22296e', 'rsrc/image/texture/grip.png' => '719404f3', 'rsrc/image/texture/panel-header-gradient.png' => 'e3b8dcfe', 'rsrc/image/texture/phlnx-bg.png' => '8d819209', 'rsrc/image/texture/pholio-background.gif' => 'ba29239c', 'rsrc/image/texture/table_header.png' => '5c433037', 'rsrc/image/texture/table_header_hover.png' => '038ec3b9', 'rsrc/image/texture/table_header_tall.png' => 'd56b434f', 'rsrc/js/application/aphlict/Aphlict.js' => '493665ee', 'rsrc/js/application/aphlict/behavior-aphlict-dropdown.js' => '2a2dba85', 'rsrc/js/application/aphlict/behavior-aphlict-listen.js' => '0a6c2de6', 'rsrc/js/application/auth/behavior-persona-login.js' => '9414ff18', 'rsrc/js/application/config/behavior-reorder-fields.js' => '938aed89', 'rsrc/js/application/conpherence/behavior-menu.js' => '7ee23816', 'rsrc/js/application/conpherence/behavior-pontificate.js' => '53f6f2dd', 'rsrc/js/application/conpherence/behavior-widget-pane.js' => '40b1ff90', 'rsrc/js/application/countdown/timer.js' => '889c96f3', 'rsrc/js/application/dashboard/behavior-dashboard-async-panel.js' => 'f1375ea5', 'rsrc/js/application/dashboard/behavior-dashboard-move-panels.js' => 'fa187a68', 'rsrc/js/application/differential/DifferentialInlineCommentEditor.js' => 'f2441746', 'rsrc/js/application/differential/behavior-add-reviewers-and-ccs.js' => '533a187b', 'rsrc/js/application/differential/behavior-comment-jump.js' => '71755c79', 'rsrc/js/application/differential/behavior-comment-preview.js' => '127f2018', 'rsrc/js/application/differential/behavior-diff-radios.js' => 'e1ff79b1', - 'rsrc/js/application/differential/behavior-dropdown-menus.js' => '7f93ef26', + 'rsrc/js/application/differential/behavior-dropdown-menus.js' => 'dfd45180', 'rsrc/js/application/differential/behavior-edit-inline-comments.js' => '00861799', 'rsrc/js/application/differential/behavior-keyboard-nav.js' => '173ce7e7', 'rsrc/js/application/differential/behavior-populate.js' => 'dfdf9f34', 'rsrc/js/application/differential/behavior-show-all-comments.js' => '7c273581', 'rsrc/js/application/differential/behavior-show-field-details.js' => '441f2137', 'rsrc/js/application/differential/behavior-show-more.js' => 'dd7e8ef5', 'rsrc/js/application/differential/behavior-toggle-files.js' => 'ca3f91eb', 'rsrc/js/application/differential/behavior-user-select.js' => 'a8d8459d', 'rsrc/js/application/diffusion/DiffusionLocateFileSource.js' => '5afdb2f8', 'rsrc/js/application/diffusion/behavior-audit-preview.js' => 'be81801d', 'rsrc/js/application/diffusion/behavior-commit-branches.js' => 'bdaf4d04', 'rsrc/js/application/diffusion/behavior-commit-graph.js' => 'f7f1289f', 'rsrc/js/application/diffusion/behavior-jump-to.js' => '9db3d160', 'rsrc/js/application/diffusion/behavior-load-blame.js' => '42126667', 'rsrc/js/application/diffusion/behavior-locate-file.js' => '6d3e1947', 'rsrc/js/application/diffusion/behavior-pull-lastmodified.js' => '2b228192', 'rsrc/js/application/doorkeeper/behavior-doorkeeper-tag.js' => 'e5822781', 'rsrc/js/application/files/behavior-icon-composer.js' => '8ef9ab58', 'rsrc/js/application/files/behavior-launch-icon-composer.js' => '48086888', 'rsrc/js/application/harbormaster/behavior-reorder-steps.js' => '957a7fde', 'rsrc/js/application/herald/HeraldRuleEditor.js' => '22d2966a', 'rsrc/js/application/herald/PathTypeahead.js' => 'f7fc67ec', 'rsrc/js/application/herald/herald-rule-editor.js' => '7ebaeed3', 'rsrc/js/application/maniphest/behavior-batch-editor.js' => 'fe80fb6d', 'rsrc/js/application/maniphest/behavior-batch-selector.js' => 'ead554ec', 'rsrc/js/application/maniphest/behavior-line-chart.js' => '64ef2fd2', 'rsrc/js/application/maniphest/behavior-list-edit.js' => 'cf76cfd5', 'rsrc/js/application/maniphest/behavior-subpriorityeditor.js' => '84845b5b', 'rsrc/js/application/maniphest/behavior-transaction-controls.js' => 'dddd43ac', 'rsrc/js/application/maniphest/behavior-transaction-expand.js' => '2f2e18aa', 'rsrc/js/application/maniphest/behavior-transaction-preview.js' => 'f8248bc5', 'rsrc/js/application/owners/OwnersPathEditor.js' => '46efd18e', 'rsrc/js/application/owners/owners-path-editor.js' => '7a68dda3', 'rsrc/js/application/passphrase/phame-credential-control.js' => '1e1c8a59', 'rsrc/js/application/phame/phame-post-preview.js' => '61d927ec', 'rsrc/js/application/pholio/behavior-pholio-mock-edit.js' => '1e1e8bb0', 'rsrc/js/application/pholio/behavior-pholio-mock-view.js' => '28497740', 'rsrc/js/application/phortune/behavior-balanced-payment-form.js' => '3b3e1664', 'rsrc/js/application/phortune/behavior-stripe-payment-form.js' => '1693a296', 'rsrc/js/application/phortune/behavior-test-payment-form.js' => 'b3e5ee60', 'rsrc/js/application/phortune/phortune-credit-card-form.js' => '2290aeef', - 'rsrc/js/application/policy/behavior-policy-control.js' => 'bc99b0f2', + 'rsrc/js/application/policy/behavior-policy-control.js' => '71b4cbcc', 'rsrc/js/application/policy/behavior-policy-rule-editor.js' => '263aeb8c', 'rsrc/js/application/ponder/behavior-votebox.js' => '327dbe61', 'rsrc/js/application/projects/behavior-project-boards.js' => 'd8e135db', 'rsrc/js/application/projects/behavior-project-create.js' => '065227cc', 'rsrc/js/application/releeph/releeph-preview-branch.js' => '9eb2cedb', 'rsrc/js/application/releeph/releeph-request-state-change.js' => 'd259e7c9', 'rsrc/js/application/releeph/releeph-request-typeahead.js' => 'cd9e7094', 'rsrc/js/application/repository/repository-crossreference.js' => '8ab282be', 'rsrc/js/application/search/behavior-reorder-queries.js' => '37871df4', 'rsrc/js/application/slowvote/behavior-slowvote-embed.js' => 'a51fdb2e', 'rsrc/js/application/transactions/behavior-transaction-comment-form.js' => '9084a36f', 'rsrc/js/application/transactions/behavior-transaction-list.js' => 'cf656c84', 'rsrc/js/application/uiexample/JavelinViewExample.js' => 'd4a14807', 'rsrc/js/application/uiexample/ReactorButtonExample.js' => '44524435', 'rsrc/js/application/uiexample/ReactorCheckboxExample.js' => '7ba325ee', 'rsrc/js/application/uiexample/ReactorFocusExample.js' => '82f568cd', 'rsrc/js/application/uiexample/ReactorInputExample.js' => 'd6ca6b1c', 'rsrc/js/application/uiexample/ReactorMouseoverExample.js' => '4e37e4de', 'rsrc/js/application/uiexample/ReactorRadioExample.js' => '858f9728', 'rsrc/js/application/uiexample/ReactorSelectExample.js' => '189e4fe3', 'rsrc/js/application/uiexample/ReactorSendClassExample.js' => 'bf97561d', 'rsrc/js/application/uiexample/ReactorSendPropertiesExample.js' => '551add57', 'rsrc/js/application/uiexample/busy-example.js' => 'fbbce3bf', 'rsrc/js/application/uiexample/gesture-example.js' => 'f42bb8c6', 'rsrc/js/application/uiexample/notification-example.js' => 'c51a6616', 'rsrc/js/core/Busy.js' => '6453c869', 'rsrc/js/core/DragAndDropFileUpload.js' => 'ae6abfba', 'rsrc/js/core/DraggableList.js' => '1681c4d4', 'rsrc/js/core/FileUpload.js' => 'a4ae61bf', 'rsrc/js/core/Hovercard.js' => '4f344388', 'rsrc/js/core/KeyboardShortcut.js' => '1ae869f2', 'rsrc/js/core/KeyboardShortcutManager.js' => 'ad7a69ca', 'rsrc/js/core/MultirowRowManager.js' => '50395a1b', 'rsrc/js/core/Notification.js' => '0c6946e7', - 'rsrc/js/core/Prefab.js' => '0326e5d0', + 'rsrc/js/core/Prefab.js' => '41ed7994', 'rsrc/js/core/ShapedRequest.js' => '7cbe244b', 'rsrc/js/core/TextAreaUtils.js' => 'b3ec3cfc', 'rsrc/js/core/ToolTip.js' => '3915d490', 'rsrc/js/core/behavior-active-nav.js' => 'c81bc98f', 'rsrc/js/core/behavior-audio-source.js' => '59b251eb', 'rsrc/js/core/behavior-autofocus.js' => '7319e029', 'rsrc/js/core/behavior-crop.js' => 'b98fc918', 'rsrc/js/core/behavior-dark-console.js' => 'e9fdb5e5', 'rsrc/js/core/behavior-device.js' => '03d6ed07', 'rsrc/js/core/behavior-drag-and-drop-textarea.js' => '4a11ea9c', 'rsrc/js/core/behavior-error-log.js' => 'a5d7cf86', 'rsrc/js/core/behavior-fancy-datepicker.js' => '5d584426', 'rsrc/js/core/behavior-file-tree.js' => 'c8728c70', 'rsrc/js/core/behavior-form.js' => 'a9aaba0c', 'rsrc/js/core/behavior-gesture.js' => 'fe2e0ba4', 'rsrc/js/core/behavior-global-drag-and-drop.js' => '8fd76bab', 'rsrc/js/core/behavior-high-security-warning.js' => '8fc1c918', 'rsrc/js/core/behavior-history-install.js' => '7ee2b591', 'rsrc/js/core/behavior-hovercard.js' => '9c808199', 'rsrc/js/core/behavior-keyboard-pager.js' => 'b657bdf8', 'rsrc/js/core/behavior-keyboard-shortcuts.js' => 'd75709e6', 'rsrc/js/core/behavior-konami.js' => '5bc2cb21', 'rsrc/js/core/behavior-lightbox-attachments.js' => '3aa45ad9', 'rsrc/js/core/behavior-line-linker.js' => 'bc778103', 'rsrc/js/core/behavior-more.js' => '9b9197be', 'rsrc/js/core/behavior-object-selector.js' => 'e6f67523', 'rsrc/js/core/behavior-oncopy.js' => 'c3e218fe', 'rsrc/js/core/behavior-phabricator-nav.js' => 'b5842a5e', 'rsrc/js/core/behavior-phabricator-remarkup-assist.js' => 'c021950a', 'rsrc/js/core/behavior-refresh-csrf.js' => '7814b593', 'rsrc/js/core/behavior-remarkup-preview.js' => 'f7379f45', 'rsrc/js/core/behavior-reveal-content.js' => '8f24abfc', 'rsrc/js/core/behavior-search-typeahead.js' => 'd8469741', 'rsrc/js/core/behavior-select-on-click.js' => '0e34ca02', 'rsrc/js/core/behavior-toggle-class.js' => 'a82a7769', 'rsrc/js/core/behavior-tokenizer.js' => 'b3a4b884', 'rsrc/js/core/behavior-tooltip.js' => '48db4145', 'rsrc/js/core/behavior-watch-anchor.js' => '06e05112', 'rsrc/js/core/behavior-workflow.js' => '0a3f3021', 'rsrc/js/core/phtize.js' => 'd254d646', 'rsrc/js/phui/behavior-phui-object-box-tabs.js' => 'a3e2244e', 'rsrc/js/phui/behavior-phui-timeline-dropdown-menu.js' => '4d94d9c3', 'rsrc/js/phuix/PHUIXActionListView.js' => 'b5c256b8', - 'rsrc/js/phuix/PHUIXActionView.js' => '19a0b148', + 'rsrc/js/phuix/PHUIXActionView.js' => '6e8cefa4', 'rsrc/js/phuix/PHUIXDropdownMenu.js' => 'bd4c8dca', 'rsrc/swf/aphlict.swf' => 'abac967d', ), 'symbols' => array( 'aphront-bars' => '231ac33c', 'aphront-contextbar-view-css' => '1c3b0529', 'aphront-dark-console-css' => '6378ef3d', 'aphront-dialog-view-css' => 'c01d24b4', 'aphront-error-view-css' => '9f1d5518', 'aphront-list-filter-view-css' => '2ae43867', 'aphront-multi-column-view-css' => '1b95ab2e', 'aphront-pager-view-css' => '2e3539af', 'aphront-panel-view-css' => '5846dfa2', 'aphront-request-failure-view-css' => 'da14df31', 'aphront-table-view-css' => '88e80148', 'aphront-tokenizer-control-css' => '36903077', 'aphront-tooltip-css' => '9c90229d', 'aphront-two-column-view-css' => '16ab3ad2', - 'aphront-typeahead-control-css' => '466ac215', + 'aphront-typeahead-control-css' => '1f4c9e23', 'auth-css' => '1e655982', 'config-options-css' => '7fedf08b', 'conpherence-menu-css' => '561348ac', 'conpherence-message-pane-css' => 'e46b612c', 'conpherence-notification-css' => '403cf598', 'conpherence-update-css' => '1099a660', 'conpherence-widget-pane-css' => 'bf275a6c', 'differential-changeset-view-css' => 'c45747f0', 'differential-core-view-css' => '7ac3cabc', 'differential-inline-comment-editor' => 'f2441746', 'differential-results-table-css' => '239924f9', 'differential-revision-add-comment-css' => 'c478bcaa', 'differential-revision-comment-css' => '48186045', 'differential-revision-history-css' => '0e8eb855', 'differential-revision-list-css' => 'f3c47d33', 'differential-table-of-contents-css' => '6bf8e1d2', 'diffusion-commit-view-css' => '92d1e8f9', 'diffusion-icons-css' => '384a0f7d', 'diffusion-source-css' => '66fdf661', 'diviner-shared-css' => '38813222', 'font-fontawesome' => '73d075c3', 'font-source-sans-pro' => '91d53463', 'global-drag-and-drop-css' => '697324ad', 'harbormaster-css' => 'cec833b7', 'herald-css' => 'c544dd1c', 'herald-rule-editor' => '22d2966a', 'herald-test-css' => '778b008e', 'inline-comment-summary-css' => '8cfd34e8', 'javelin-aphlict' => '493665ee', 'javelin-behavior' => '8a3ed18b', 'javelin-behavior-aphlict-dropdown' => '2a2dba85', 'javelin-behavior-aphlict-listen' => '0a6c2de6', 'javelin-behavior-aphront-basic-tokenizer' => 'b3a4b884', 'javelin-behavior-aphront-crop' => 'b98fc918', 'javelin-behavior-aphront-drag-and-drop-textarea' => '4a11ea9c', 'javelin-behavior-aphront-form-disable-on-submit' => 'a9aaba0c', 'javelin-behavior-aphront-more' => '9b9197be', 'javelin-behavior-audio-source' => '59b251eb', 'javelin-behavior-audit-preview' => 'be81801d', 'javelin-behavior-balanced-payment-form' => '3b3e1664', 'javelin-behavior-config-reorder-fields' => '938aed89', 'javelin-behavior-conpherence-menu' => '7ee23816', 'javelin-behavior-conpherence-pontificate' => '53f6f2dd', 'javelin-behavior-conpherence-widget-pane' => '40b1ff90', 'javelin-behavior-countdown-timer' => '889c96f3', 'javelin-behavior-dark-console' => 'e9fdb5e5', 'javelin-behavior-dashboard-async-panel' => 'f1375ea5', 'javelin-behavior-dashboard-move-panels' => 'fa187a68', 'javelin-behavior-device' => '03d6ed07', 'javelin-behavior-differential-add-reviewers-and-ccs' => '533a187b', 'javelin-behavior-differential-comment-jump' => '71755c79', 'javelin-behavior-differential-diff-radios' => 'e1ff79b1', - 'javelin-behavior-differential-dropdown-menus' => '7f93ef26', + 'javelin-behavior-differential-dropdown-menus' => 'dfd45180', 'javelin-behavior-differential-edit-inline-comments' => '00861799', 'javelin-behavior-differential-feedback-preview' => '127f2018', 'javelin-behavior-differential-keyboard-navigation' => '173ce7e7', 'javelin-behavior-differential-populate' => 'dfdf9f34', 'javelin-behavior-differential-show-field-details' => '441f2137', 'javelin-behavior-differential-show-more' => 'dd7e8ef5', 'javelin-behavior-differential-toggle-files' => 'ca3f91eb', 'javelin-behavior-differential-user-select' => 'a8d8459d', 'javelin-behavior-diffusion-commit-branches' => 'bdaf4d04', 'javelin-behavior-diffusion-commit-graph' => 'f7f1289f', 'javelin-behavior-diffusion-jump-to' => '9db3d160', 'javelin-behavior-diffusion-locate-file' => '6d3e1947', 'javelin-behavior-diffusion-pull-lastmodified' => '2b228192', 'javelin-behavior-doorkeeper-tag' => 'e5822781', 'javelin-behavior-error-log' => 'a5d7cf86', 'javelin-behavior-fancy-datepicker' => '5d584426', 'javelin-behavior-global-drag-and-drop' => '8fd76bab', 'javelin-behavior-harbormaster-reorder-steps' => '957a7fde', 'javelin-behavior-herald-rule-editor' => '7ebaeed3', 'javelin-behavior-high-security-warning' => '8fc1c918', 'javelin-behavior-history-install' => '7ee2b591', 'javelin-behavior-icon-composer' => '8ef9ab58', 'javelin-behavior-konami' => '5bc2cb21', 'javelin-behavior-launch-icon-composer' => '48086888', 'javelin-behavior-lightbox-attachments' => '3aa45ad9', 'javelin-behavior-line-chart' => '64ef2fd2', 'javelin-behavior-load-blame' => '42126667', 'javelin-behavior-maniphest-batch-editor' => 'fe80fb6d', 'javelin-behavior-maniphest-batch-selector' => 'ead554ec', 'javelin-behavior-maniphest-list-editor' => 'cf76cfd5', 'javelin-behavior-maniphest-subpriority-editor' => '84845b5b', 'javelin-behavior-maniphest-transaction-controls' => 'dddd43ac', 'javelin-behavior-maniphest-transaction-expand' => '2f2e18aa', 'javelin-behavior-maniphest-transaction-preview' => 'f8248bc5', 'javelin-behavior-owners-path-editor' => '7a68dda3', 'javelin-behavior-passphrase-credential-control' => '1e1c8a59', 'javelin-behavior-persona-login' => '9414ff18', 'javelin-behavior-phabricator-active-nav' => 'c81bc98f', 'javelin-behavior-phabricator-autofocus' => '7319e029', 'javelin-behavior-phabricator-busy-example' => 'fbbce3bf', 'javelin-behavior-phabricator-file-tree' => 'c8728c70', 'javelin-behavior-phabricator-gesture' => 'fe2e0ba4', 'javelin-behavior-phabricator-gesture-example' => 'f42bb8c6', 'javelin-behavior-phabricator-hovercards' => '9c808199', 'javelin-behavior-phabricator-keyboard-pager' => 'b657bdf8', 'javelin-behavior-phabricator-keyboard-shortcuts' => 'd75709e6', 'javelin-behavior-phabricator-line-linker' => 'bc778103', 'javelin-behavior-phabricator-nav' => 'b5842a5e', 'javelin-behavior-phabricator-notification-example' => 'c51a6616', 'javelin-behavior-phabricator-object-selector' => 'e6f67523', 'javelin-behavior-phabricator-oncopy' => 'c3e218fe', 'javelin-behavior-phabricator-remarkup-assist' => 'c021950a', 'javelin-behavior-phabricator-reveal-content' => '8f24abfc', 'javelin-behavior-phabricator-search-typeahead' => 'd8469741', 'javelin-behavior-phabricator-show-all-transactions' => '7c273581', 'javelin-behavior-phabricator-tooltips' => '48db4145', 'javelin-behavior-phabricator-transaction-comment-form' => '9084a36f', 'javelin-behavior-phabricator-transaction-list' => 'cf656c84', 'javelin-behavior-phabricator-watch-anchor' => '06e05112', 'javelin-behavior-phame-post-preview' => '61d927ec', 'javelin-behavior-pholio-mock-edit' => '1e1e8bb0', 'javelin-behavior-pholio-mock-view' => '28497740', 'javelin-behavior-phui-object-box-tabs' => 'a3e2244e', 'javelin-behavior-phui-timeline-dropdown-menu' => '4d94d9c3', - 'javelin-behavior-policy-control' => 'bc99b0f2', + 'javelin-behavior-policy-control' => '71b4cbcc', 'javelin-behavior-policy-rule-editor' => '263aeb8c', 'javelin-behavior-ponder-votebox' => '327dbe61', 'javelin-behavior-project-boards' => 'd8e135db', 'javelin-behavior-project-create' => '065227cc', 'javelin-behavior-refresh-csrf' => '7814b593', 'javelin-behavior-releeph-preview-branch' => '9eb2cedb', 'javelin-behavior-releeph-request-state-change' => 'd259e7c9', 'javelin-behavior-releeph-request-typeahead' => 'cd9e7094', 'javelin-behavior-remarkup-preview' => 'f7379f45', 'javelin-behavior-repository-crossreference' => '8ab282be', 'javelin-behavior-search-reorder-queries' => '37871df4', 'javelin-behavior-select-on-click' => '0e34ca02', 'javelin-behavior-slowvote-embed' => 'a51fdb2e', 'javelin-behavior-stripe-payment-form' => '1693a296', 'javelin-behavior-test-payment-form' => 'b3e5ee60', 'javelin-behavior-toggle-class' => 'a82a7769', 'javelin-behavior-view-placeholder' => '2fa810fc', 'javelin-behavior-workflow' => '0a3f3021', 'javelin-color' => '7e41274a', 'javelin-cookie' => '6b3dcf44', 'javelin-diffusion-locate-file-source' => '5afdb2f8', 'javelin-dom' => '07d99a3d', 'javelin-dynval' => 'f6555212', 'javelin-event' => '69815cac', 'javelin-fx' => '54b612ba', 'javelin-history' => 'c60f4327', 'javelin-install' => '52a92793', 'javelin-json' => '08e56a4e', 'javelin-magical-init' => 'b88ab49e', 'javelin-mask' => 'b9f26029', 'javelin-reactor' => '77b1cf6f', 'javelin-reactor-dom' => 'b6d401d6', 'javelin-reactor-node-calmer' => '76f4ebed', 'javelin-reactornode' => 'b4c30592', 'javelin-request' => '7bad574b', 'javelin-resource' => '356de121', 'javelin-routable' => 'b3e7d692', 'javelin-router' => '29274e2b', 'javelin-stratcom' => 'c293f7b9', 'javelin-tokenizer' => 'e7c21fb3', 'javelin-typeahead' => 'c54eeefb', 'javelin-typeahead-composite-source' => '84f34ab1', 'javelin-typeahead-normalizer' => '5f850b5c', 'javelin-typeahead-ondemand-source' => 'a79b75a4', 'javelin-typeahead-preloaded-source' => '66815d9c', 'javelin-typeahead-source' => '62e18640', 'javelin-typeahead-static-source' => 'cdde23f1', 'javelin-uri' => 'd9a9b862', 'javelin-util' => '65b0b249', 'javelin-vector' => 'bd0aedcd', 'javelin-view' => '0f764c35', 'javelin-view-html' => 'e5b406f9', 'javelin-view-interpreter' => '0c33c1a0', 'javelin-view-renderer' => '6c2b09a2', 'javelin-view-visitor' => 'efe49472', 'javelin-workflow' => '09b15cf1', 'lightbox-attachment-css' => '7acac05d', 'maniphest-batch-editor' => '8f380ebc', 'maniphest-report-css' => '6fc16517', 'maniphest-task-edit-css' => '8e23031b', 'maniphest-task-summary-css' => '6df1a768', 'multirow-row-manager' => '50395a1b', 'owners-path-editor' => '46efd18e', 'owners-path-editor-css' => '2f00933b', 'paste-css' => 'aa1767d1', 'path-typeahead' => 'f7fc67ec', 'people-profile-css' => 'ba7b2762', 'phabricator-action-header-view-css' => 'c14dfc57', 'phabricator-action-list-view-css' => 'dcd9875f', 'phabricator-application-launch-view-css' => 'd290ba21', 'phabricator-busy' => '6453c869', 'phabricator-chatlog-css' => '852140ff', 'phabricator-content-source-view-css' => '4b8b05d4', 'phabricator-core-css' => '40151074', 'phabricator-countdown-css' => '86b7b0a0', 'phabricator-crumbs-view-css' => '6a23399c', 'phabricator-dashboard-css' => '2b41640b', 'phabricator-drag-and-drop-file-upload' => 'ae6abfba', 'phabricator-draggable-list' => '1681c4d4', 'phabricator-fatal-config-template-css' => '25d446d6', 'phabricator-feed-css' => '0d17c209', 'phabricator-file-upload' => 'a4ae61bf', 'phabricator-filetree-view-css' => 'a8c86ace', 'phabricator-flag-css' => '5337623f', 'phabricator-hovercard' => '4f344388', 'phabricator-hovercard-view-css' => '46a13cf0', 'phabricator-jump-nav' => 'f0c5e726', 'phabricator-keyboard-shortcut' => '1ae869f2', 'phabricator-keyboard-shortcut-manager' => 'ad7a69ca', 'phabricator-main-menu-view' => '0207239c', 'phabricator-nav-view-css' => '80e60fc1', 'phabricator-notification' => '0c6946e7', 'phabricator-notification-css' => 'ef2c9b34', 'phabricator-notification-menu-css' => '99ffef72', 'phabricator-object-selector-css' => '029a133d', 'phabricator-phtize' => 'd254d646', - 'phabricator-prefab' => '0326e5d0', + 'phabricator-prefab' => '41ed7994', 'phabricator-profile-css' => '33e6f703', 'phabricator-project-tag-css' => '095c9404', 'phabricator-remarkup-css' => '80c3a48c', 'phabricator-search-results-css' => 'f240504c', 'phabricator-settings-css' => 'ea8f5915', 'phabricator-shaped-request' => '7cbe244b', 'phabricator-side-menu-view-css' => '503699d0', 'phabricator-slowvote-css' => '266df6a1', 'phabricator-source-code-view-css' => '62a99814', 'phabricator-standard-page-view' => '517cdfb1', 'phabricator-textareautils' => 'b3ec3cfc', 'phabricator-tooltip' => '3915d490', 'phabricator-transaction-view-css' => 'ce491938', 'phabricator-ui-example-css' => '528b19de', 'phabricator-uiexample-javelin-view' => 'd4a14807', 'phabricator-uiexample-reactor-button' => '44524435', 'phabricator-uiexample-reactor-checkbox' => '7ba325ee', 'phabricator-uiexample-reactor-focus' => '82f568cd', 'phabricator-uiexample-reactor-input' => 'd6ca6b1c', 'phabricator-uiexample-reactor-mouseover' => '4e37e4de', 'phabricator-uiexample-reactor-radio' => '858f9728', 'phabricator-uiexample-reactor-select' => '189e4fe3', 'phabricator-uiexample-reactor-sendclass' => 'bf97561d', 'phabricator-uiexample-reactor-sendproperties' => '551add57', 'phabricator-zindex-css' => 'efb673ac', 'phame-css' => '19ecc703', 'pholio-css' => 'e059f955', 'pholio-edit-css' => 'b9e59b6d', 'pholio-inline-comments-css' => '52be33f0', 'phortune-credit-card-form' => '2290aeef', 'phortune-credit-card-form-css' => 'b25b4beb', 'phrequent-css' => 'ffc185ad', 'phriction-document-css' => '7d7f0071', 'phui-box-css' => '7b3a2eed', 'phui-button-css' => '3dbdbf0d', 'phui-calendar-css' => '5e1ad989', 'phui-calendar-day-css' => 'de035c8a', 'phui-calendar-list-css' => 'c1d0ca59', 'phui-calendar-month-css' => 'a92e47d2', 'phui-document-view-css' => '3b078dc0', 'phui-feed-story-css' => '3a59c2cf', 'phui-font-icon-base-css' => '74cfb6a9', 'phui-fontkit-css' => 'de84aa4a', 'phui-form-css' => 'b78ec020', 'phui-form-view-css' => '867463b4', - 'phui-header-view-css' => '5d245c9c', - 'phui-icon-view-css' => '00abbd26', + 'phui-header-view-css' => '689dbc38', + 'phui-icon-view-css' => 'ef701b9b', 'phui-info-panel-css' => '27ea50a1', 'phui-list-view-css' => '65eab261', 'phui-object-box-css' => 'ce92d8ec', 'phui-object-item-list-view-css' => '64b6b266', 'phui-pinboard-view-css' => '874c22f9', - 'phui-property-list-view-css' => 'af4b381f', + 'phui-property-list-view-css' => 'c7cbe471', 'phui-remarkup-preview-css' => '19ad512b', 'phui-spacing-css' => '042804d6', 'phui-status-list-view-css' => '2f562399', 'phui-tag-view-css' => '5d09d99e', 'phui-text-css' => '23e9b4b7', 'phui-timeline-view-css' => '15ff2a9f', 'phui-workboard-view-css' => '2bf82d00', 'phui-workpanel-view-css' => 'fddd97bf', 'phuix-action-list-view' => 'b5c256b8', - 'phuix-action-view' => '19a0b148', + 'phuix-action-view' => '6e8cefa4', 'phuix-dropdown-menu' => 'bd4c8dca', 'policy-css' => '957ea14c', 'policy-edit-css' => '05cca26a', 'policy-transaction-detail-css' => '82100a43', 'ponder-comment-table-css' => '6cdccea7', 'ponder-feed-view-css' => 'e62615b6', 'ponder-post-css' => 'ebab8a70', 'ponder-vote-css' => '8ed6ed8b', 'raphael-core' => '51ee6b43', 'raphael-g' => '40dde778', 'raphael-g-line' => '40da039e', 'releeph-core' => '9b3c5733', 'releeph-preview-branch' => 'b7a6f4a5', 'releeph-request-differential-create-dialog' => '8d8b92cd', 'releeph-request-typeahead-css' => '667a48ae', 'setup-issue-css' => '69e640e7', 'sprite-actions-css' => '969ad0e5', 'sprite-apps-css' => 'a0f5d4af', 'sprite-apps-large-css' => 'd7ef733e', 'sprite-apps-xlarge-css' => 'db66c878', 'sprite-buttonbar-css' => 'ba1c5738', 'sprite-conpherence-css' => '3b4a0487', 'sprite-docs-css' => '5f65d0da', 'sprite-gradient-css' => 'a10def53', 'sprite-login-css' => '8d10fb28', 'sprite-main-header-css' => '92720ee2', 'sprite-menu-css' => '8da53882', 'sprite-minicons-css' => 'df4f76fe', 'sprite-payments-css' => 'cc085d44', 'sprite-projects-css' => '7578fa56', 'sprite-remarkup-css' => '5c396a57', - 'sprite-status-css' => '25d7f92f', 'sprite-tokens-css' => '1706b943', 'subscribers-list-css' => '5bb30c78', 'syntax-highlighting-css' => '3c18c1cb', 'tokens-css' => '3d0f239e', ), 'requires' => array( '00861799' => array( 0 => 'javelin-behavior', 1 => 'javelin-stratcom', 2 => 'javelin-dom', 3 => 'javelin-util', 4 => 'javelin-vector', 5 => 'differential-inline-comment-editor', ), '029a133d' => array( 0 => 'aphront-dialog-view-css', ), - '0326e5d0' => - array( - 0 => 'javelin-install', - 1 => 'javelin-util', - 2 => 'javelin-dom', - 3 => 'javelin-typeahead', - 4 => 'javelin-tokenizer', - 5 => 'javelin-typeahead-preloaded-source', - 6 => 'javelin-typeahead-ondemand-source', - 7 => 'javelin-dom', - 8 => 'javelin-stratcom', - 9 => 'javelin-util', - ), '03d6ed07' => array( 0 => 'javelin-behavior', 1 => 'javelin-stratcom', 2 => 'javelin-dom', 3 => 'javelin-vector', 4 => 'javelin-install', ), '065227cc' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-stratcom', 3 => 'javelin-workflow', ), '06e05112' => array( 0 => 'javelin-behavior', 1 => 'javelin-stratcom', 2 => 'javelin-dom', 3 => 'javelin-vector', ), '07d99a3d' => array( 0 => 'javelin-magical-init', 1 => 'javelin-install', 2 => 'javelin-util', 3 => 'javelin-vector', 4 => 'javelin-stratcom', ), '08e56a4e' => array( 0 => 'javelin-install', ), '09b15cf1' => array( 0 => 'javelin-stratcom', 1 => 'javelin-request', 2 => 'javelin-dom', 3 => 'javelin-vector', 4 => 'javelin-install', 5 => 'javelin-util', 6 => 'javelin-mask', 7 => 'javelin-uri', 8 => 'javelin-routable', ), '0a3f3021' => array( 0 => 'javelin-behavior', 1 => 'javelin-stratcom', 2 => 'javelin-workflow', 3 => 'javelin-dom', 4 => 'javelin-router', ), '0a6c2de6' => array( 0 => 'javelin-behavior', 1 => 'javelin-aphlict', 2 => 'javelin-stratcom', 3 => 'javelin-request', 4 => 'javelin-uri', 5 => 'javelin-dom', 6 => 'javelin-json', 7 => 'javelin-router', 8 => 'phabricator-notification', ), '0c33c1a0' => array( 0 => 'javelin-view', 1 => 'javelin-install', 2 => 'javelin-dom', ), '0c6946e7' => array( 0 => 'javelin-install', 1 => 'javelin-dom', 2 => 'javelin-stratcom', 3 => 'javelin-util', 4 => 'phabricator-notification-css', ), '0e34ca02' => array( 0 => 'javelin-behavior', 1 => 'javelin-stratcom', 2 => 'javelin-dom', ), '0f764c35' => array( 0 => 'javelin-install', 1 => 'javelin-util', ), '127f2018' => array( 0 => 'javelin-behavior', 1 => 'javelin-stratcom', 2 => 'javelin-dom', 3 => 'javelin-request', 4 => 'javelin-util', 5 => 'phabricator-shaped-request', ), '1681c4d4' => array( 0 => 'javelin-install', 1 => 'javelin-dom', 2 => 'javelin-stratcom', 3 => 'javelin-util', 4 => 'javelin-vector', 5 => 'javelin-magical-init', ), '1693a296' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'phortune-credit-card-form', ), '173ce7e7' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-stratcom', 3 => 'phabricator-keyboard-shortcut', ), '189e4fe3' => array( 0 => 'javelin-install', 1 => 'javelin-dom', 2 => 'javelin-reactor-dom', ), - '19a0b148' => - array( - 0 => 'javelin-install', - 1 => 'javelin-dom', - 2 => 'javelin-util', - ), '1ae869f2' => array( 0 => 'javelin-install', 1 => 'javelin-util', 2 => 'phabricator-keyboard-shortcut-manager', ), '1e1c8a59' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-stratcom', 3 => 'javelin-workflow', 4 => 'javelin-util', 5 => 'javelin-uri', ), '1e1e8bb0' => array( 0 => 'javelin-behavior', 1 => 'javelin-stratcom', 2 => 'javelin-dom', 3 => 'javelin-workflow', 4 => 'phabricator-phtize', 5 => 'phabricator-drag-and-drop-file-upload', 6 => 'phabricator-draggable-list', ), '2290aeef' => array( 0 => 'javelin-install', 1 => 'javelin-dom', 2 => 'javelin-json', 3 => 'javelin-workflow', 4 => 'javelin-util', ), '22d2966a' => array( 0 => 'multirow-row-manager', 1 => 'javelin-install', 2 => 'javelin-util', 3 => 'javelin-dom', 4 => 'javelin-stratcom', 5 => 'javelin-json', 6 => 'phabricator-prefab', ), '263aeb8c' => array( 0 => 'javelin-behavior', 1 => 'multirow-row-manager', 2 => 'javelin-dom', 3 => 'javelin-util', 4 => 'phabricator-prefab', 5 => 'javelin-tokenizer', 6 => 'javelin-typeahead', 7 => 'javelin-typeahead-preloaded-source', 8 => 'javelin-json', ), '29274e2b' => array( 0 => 'javelin-install', 1 => 'javelin-util', ), '2a2dba85' => array( 0 => 'javelin-behavior', 1 => 'javelin-request', 2 => 'javelin-stratcom', 3 => 'javelin-vector', 4 => 'javelin-dom', 5 => 'javelin-uri', 6 => 'javelin-behavior-device', ), '2b228192' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-util', 3 => 'javelin-workflow', 4 => 'javelin-json', ), '2f2e18aa' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-workflow', 3 => 'javelin-stratcom', ), '2fa810fc' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-view-renderer', 3 => 'javelin-install', ), '327dbe61' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-util', 3 => 'javelin-stratcom', 4 => 'javelin-request', ), '356de121' => array( 0 => 'javelin-util', 1 => 'javelin-uri', 2 => 'javelin-install', ), '37871df4' => array( 0 => 'javelin-behavior', 1 => 'javelin-stratcom', 2 => 'javelin-workflow', 3 => 'javelin-dom', 4 => 'phabricator-draggable-list', ), '3915d490' => array( 0 => 'javelin-install', 1 => 'javelin-util', 2 => 'javelin-dom', 3 => 'javelin-vector', ), '3aa45ad9' => array( 0 => 'javelin-behavior', 1 => 'javelin-stratcom', 2 => 'javelin-dom', 3 => 'javelin-mask', 4 => 'javelin-util', 5 => 'phabricator-busy', ), '3b3e1664' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'phortune-credit-card-form', ), '40b1ff90' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-stratcom', 3 => 'javelin-workflow', 4 => 'javelin-util', 5 => 'phabricator-notification', 6 => 'javelin-behavior-device', 7 => 'phuix-dropdown-menu', 8 => 'phuix-action-list-view', 9 => 'phuix-action-view', ), + '41ed7994' => + array( + 0 => 'javelin-install', + 1 => 'javelin-util', + 2 => 'javelin-dom', + 3 => 'javelin-typeahead', + 4 => 'javelin-tokenizer', + 5 => 'javelin-typeahead-preloaded-source', + 6 => 'javelin-typeahead-ondemand-source', + 7 => 'javelin-dom', + 8 => 'javelin-stratcom', + 9 => 'javelin-util', + ), '441f2137' => array( 0 => 'javelin-behavior', 1 => 'javelin-stratcom', 2 => 'javelin-dom', ), '46efd18e' => array( 0 => 'multirow-row-manager', 1 => 'javelin-install', 2 => 'path-typeahead', 3 => 'javelin-dom', 4 => 'javelin-util', 5 => 'phabricator-prefab', ), '48db4145' => array( 0 => 'javelin-behavior', 1 => 'javelin-behavior-device', 2 => 'javelin-stratcom', 3 => 'phabricator-tooltip', ), '493665ee' => array( 0 => 'javelin-install', 1 => 'javelin-util', ), '4a11ea9c' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'phabricator-drag-and-drop-file-upload', 3 => 'phabricator-textareautils', ), '4d94d9c3' => array( 0 => 'javelin-behavior', 1 => 'javelin-stratcom', 2 => 'javelin-dom', 3 => 'phuix-dropdown-menu', ), '4e37e4de' => array( 0 => 'javelin-install', 1 => 'javelin-dom', 2 => 'javelin-reactor-dom', ), '4f344388' => array( 0 => 'javelin-install', 1 => 'javelin-dom', 2 => 'javelin-vector', 3 => 'javelin-request', 4 => 'javelin-uri', ), '50395a1b' => array( 0 => 'javelin-install', 1 => 'javelin-stratcom', 2 => 'javelin-dom', 3 => 'javelin-util', ), '52a92793' => array( 0 => 'javelin-util', 1 => 'javelin-magical-init', ), '533a187b' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'phabricator-prefab', ), '53f6f2dd' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-util', 3 => 'javelin-workflow', 4 => 'javelin-stratcom', ), '54b612ba' => array( 0 => 'javelin-color', 1 => 'javelin-install', 2 => 'javelin-util', ), '551add57' => array( 0 => 'javelin-install', 1 => 'javelin-dom', 2 => 'javelin-reactor-dom', ), '59b251eb' => array( 0 => 'javelin-behavior', 1 => 'javelin-stratcom', 2 => 'javelin-vector', 3 => 'javelin-dom', ), '5afdb2f8' => array( 0 => 'javelin-install', 1 => 'javelin-dom', 2 => 'javelin-typeahead-preloaded-source', 3 => 'javelin-util', ), '5bc2cb21' => array( 0 => 'javelin-behavior', 1 => 'javelin-stratcom', ), '5d584426' => array( 0 => 'javelin-behavior', 1 => 'javelin-util', 2 => 'javelin-dom', 3 => 'javelin-stratcom', 4 => 'javelin-vector', ), '5f850b5c' => array( 0 => 'javelin-install', ), '61d927ec' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-util', 3 => 'phabricator-shaped-request', ), - '62e18640' => - array( - 0 => 'javelin-install', - 1 => 'javelin-util', - 2 => 'javelin-dom', - 3 => 'javelin-typeahead-normalizer', - ), '6453c869' => array( 0 => 'javelin-install', 1 => 'javelin-dom', 2 => 'javelin-fx', ), '64ef2fd2' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-vector', ), '66815d9c' => array( 0 => 'javelin-install', 1 => 'javelin-util', 2 => 'javelin-request', 3 => 'javelin-typeahead-source', ), '69815cac' => array( 0 => 'javelin-install', ), '6b3dcf44' => array( 0 => 'javelin-install', 1 => 'javelin-util', ), '6c2b09a2' => array( 0 => 'javelin-install', 1 => 'javelin-util', ), '6d3e1947' => array( 0 => 'javelin-behavior', 1 => 'javelin-diffusion-locate-file-source', 2 => 'javelin-dom', 3 => 'javelin-typeahead', 4 => 'javelin-uri', ), + '6e8cefa4' => + array( + 0 => 'javelin-install', + 1 => 'javelin-dom', + 2 => 'javelin-util', + ), '71755c79' => array( 0 => 'javelin-behavior', 1 => 'javelin-stratcom', 2 => 'javelin-dom', ), + '71b4cbcc' => + array( + 0 => 'javelin-behavior', + 1 => 'javelin-dom', + 2 => 'javelin-util', + 3 => 'phuix-dropdown-menu', + 4 => 'phuix-action-list-view', + 5 => 'phuix-action-view', + 6 => 'javelin-workflow', + ), '7319e029' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', ), + '62e18640' => + array( + 0 => 'javelin-install', + 1 => 'javelin-util', + 2 => 'javelin-dom', + 3 => 'javelin-typeahead-normalizer', + ), '76f4ebed' => array( 0 => 'javelin-install', 1 => 'javelin-reactor', 2 => 'javelin-util', ), '77b1cf6f' => array( 0 => 'javelin-install', 1 => 'javelin-util', ), '7814b593' => array( 0 => 'javelin-request', 1 => 'javelin-behavior', 2 => 'javelin-dom', 3 => 'javelin-router', 4 => 'javelin-util', 5 => 'phabricator-busy', ), '7a68dda3' => array( 0 => 'owners-path-editor', 1 => 'javelin-behavior', ), '7ba325ee' => array( 0 => 'javelin-install', 1 => 'javelin-dom', 2 => 'javelin-reactor-dom', ), '7bad574b' => array( 0 => 'javelin-install', 1 => 'javelin-stratcom', 2 => 'javelin-util', 3 => 'javelin-behavior', 4 => 'javelin-json', 5 => 'javelin-dom', 6 => 'javelin-resource', 7 => 'javelin-routable', ), '7c273581' => array( 0 => 'javelin-behavior', 1 => 'javelin-stratcom', 2 => 'javelin-dom', ), '7cbe244b' => array( 0 => 'javelin-install', 1 => 'javelin-util', 2 => 'javelin-request', 3 => 'javelin-router', ), '7e41274a' => array( 0 => 'javelin-install', ), '7ebaeed3' => array( 0 => 'herald-rule-editor', 1 => 'javelin-behavior', ), '7ee23816' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-util', 3 => 'javelin-stratcom', 4 => 'javelin-workflow', 5 => 'javelin-behavior-device', 6 => 'javelin-history', 7 => 'javelin-vector', 8 => 'phabricator-shaped-request', ), '7ee2b591' => array( 0 => 'javelin-behavior', 1 => 'javelin-history', ), - '7f93ef26' => - array( - 0 => 'javelin-behavior', - 1 => 'javelin-dom', - 2 => 'javelin-util', - 3 => 'javelin-stratcom', - 4 => 'phuix-dropdown-menu', - 5 => 'phuix-action-list-view', - 6 => 'phuix-action-view', - 7 => 'phabricator-phtize', - ), '82f568cd' => array( 0 => 'javelin-install', 1 => 'javelin-dom', 2 => 'javelin-reactor-dom', ), '84845b5b' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-stratcom', 3 => 'javelin-workflow', 4 => 'phabricator-draggable-list', ), '84f34ab1' => array( 0 => 'javelin-install', 1 => 'javelin-typeahead-source', 2 => 'javelin-util', ), '858f9728' => array( 0 => 'javelin-install', 1 => 'javelin-dom', 2 => 'javelin-reactor-dom', ), '889c96f3' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', ), '8a3ed18b' => array( 0 => 'javelin-magical-init', 1 => 'javelin-util', ), '8ab282be' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-stratcom', 3 => 'javelin-uri', ), '8ef9ab58' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-stratcom', ), '8f24abfc' => array( 0 => 'javelin-behavior', 1 => 'javelin-stratcom', 2 => 'javelin-dom', ), '8fc1c918' => array( 0 => 'javelin-behavior', 1 => 'javelin-uri', 2 => 'phabricator-notification', ), '8fd76bab' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-uri', 3 => 'javelin-mask', 4 => 'phabricator-drag-and-drop-file-upload', ), '9084a36f' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-util', 3 => 'javelin-fx', 4 => 'javelin-request', 5 => 'phabricator-shaped-request', ), '938aed89' => array( 0 => 'javelin-behavior', 1 => 'javelin-stratcom', 2 => 'javelin-dom', 3 => 'javelin-json', 4 => 'phabricator-draggable-list', ), '9414ff18' => array( 0 => 'javelin-behavior', 1 => 'javelin-resource', 2 => 'javelin-stratcom', 3 => 'javelin-workflow', 4 => 'javelin-util', ), '957a7fde' => array( 0 => 'javelin-behavior', 1 => 'javelin-stratcom', 2 => 'javelin-workflow', 3 => 'javelin-dom', 4 => 'phabricator-draggable-list', ), '9b9197be' => array( 0 => 'javelin-behavior', 1 => 'javelin-stratcom', 2 => 'javelin-dom', ), '9c808199' => array( 0 => 'javelin-behavior', 1 => 'javelin-behavior-device', 2 => 'javelin-stratcom', 3 => 'javelin-vector', 4 => 'phabricator-hovercard', ), '9db3d160' => array( 0 => 'javelin-behavior', 1 => 'javelin-vector', 2 => 'javelin-dom', ), '9eb2cedb' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-uri', 3 => 'javelin-request', ), 'a3e2244e' => array( 0 => 'javelin-behavior', 1 => 'javelin-stratcom', 2 => 'javelin-dom', ), 'a4ae61bf' => array( 0 => 'javelin-install', 1 => 'javelin-dom', 2 => 'phabricator-notification', ), 'a51fdb2e' => array( 0 => 'javelin-behavior', 1 => 'javelin-request', 2 => 'javelin-stratcom', 3 => 'javelin-dom', ), 'a5d7cf86' => array( 0 => 'javelin-dom', ), 'a79b75a4' => array( 0 => 'javelin-install', 1 => 'javelin-util', 2 => 'javelin-request', 3 => 'javelin-typeahead-source', ), 'a82a7769' => array( 0 => 'javelin-behavior', 1 => 'javelin-stratcom', 2 => 'javelin-dom', ), 'a8d8459d' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-stratcom', ), 'a9aaba0c' => array( 0 => 'javelin-behavior', 1 => 'javelin-stratcom', 2 => 'javelin-dom', ), 'ad7a69ca' => array( 0 => 'javelin-install', 1 => 'javelin-util', 2 => 'javelin-stratcom', 3 => 'javelin-dom', 4 => 'javelin-vector', ), 'ae6abfba' => array( 0 => 'javelin-install', 1 => 'javelin-util', 2 => 'javelin-request', 3 => 'javelin-dom', 4 => 'javelin-uri', 5 => 'phabricator-file-upload', ), 'b3a4b884' => array( 0 => 'javelin-behavior', 1 => 'phabricator-prefab', ), 'b3e5ee60' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'phortune-credit-card-form', ), 'b3e7d692' => array( 0 => 'javelin-install', ), 'b3ec3cfc' => array( 0 => 'javelin-install', ), 'b4c30592' => array( 0 => 'javelin-install', 1 => 'javelin-reactor', 2 => 'javelin-util', 3 => 'javelin-reactor-node-calmer', ), 'b5842a5e' => array( 0 => 'javelin-behavior', 1 => 'javelin-behavior-device', 2 => 'javelin-stratcom', 3 => 'javelin-dom', 4 => 'javelin-magical-init', 5 => 'javelin-vector', 6 => 'javelin-request', 7 => 'javelin-util', ), 'b5c256b8' => array( 0 => 'javelin-install', 1 => 'javelin-dom', ), 'b657bdf8' => array( 0 => 'javelin-behavior', 1 => 'javelin-uri', 2 => 'phabricator-keyboard-shortcut', ), 'b6d401d6' => array( 0 => 'javelin-dom', 1 => 'javelin-dynval', 2 => 'javelin-reactor', 3 => 'javelin-reactornode', 4 => 'javelin-install', 5 => 'javelin-util', ), 'b98fc918' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-vector', 3 => 'javelin-magical-init', ), 'b9f26029' => array( 0 => 'javelin-install', 1 => 'javelin-dom', ), 'bc778103' => array( 0 => 'javelin-behavior', 1 => 'javelin-stratcom', 2 => 'javelin-dom', 3 => 'javelin-history', ), - 'bc99b0f2' => - array( - 0 => 'javelin-behavior', - 1 => 'javelin-dom', - 2 => 'javelin-util', - 3 => 'phuix-dropdown-menu', - 4 => 'phuix-action-list-view', - 5 => 'phuix-action-view', - 6 => 'javelin-workflow', - ), 'bd0aedcd' => array( 0 => 'javelin-install', 1 => 'javelin-event', ), 'bd4c8dca' => array( 0 => 'javelin-install', 1 => 'javelin-util', 2 => 'javelin-dom', 3 => 'javelin-vector', 4 => 'javelin-stratcom', ), 'bdaf4d04' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-util', 3 => 'javelin-request', ), 'be81801d' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-util', 3 => 'phabricator-shaped-request', ), 'bf97561d' => array( 0 => 'javelin-install', 1 => 'javelin-dom', 2 => 'javelin-reactor-dom', ), 'c021950a' => array( 0 => 'javelin-behavior', 1 => 'javelin-stratcom', 2 => 'javelin-dom', 3 => 'phabricator-phtize', 4 => 'phabricator-textareautils', 5 => 'javelin-workflow', 6 => 'javelin-vector', ), 'c293f7b9' => array( 0 => 'javelin-install', 1 => 'javelin-event', 2 => 'javelin-util', 3 => 'javelin-magical-init', ), 'c3e218fe' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', ), 'c51a6616' => array( 0 => 'phabricator-notification', 1 => 'javelin-stratcom', 2 => 'javelin-behavior', ), 'c54eeefb' => array( 0 => 'javelin-install', 1 => 'javelin-dom', 2 => 'javelin-vector', 3 => 'javelin-util', ), 'c60f4327' => array( 0 => 'javelin-stratcom', 1 => 'javelin-install', 2 => 'javelin-uri', 3 => 'javelin-util', ), 'c81bc98f' => array( 0 => 'javelin-behavior', 1 => 'javelin-stratcom', 2 => 'javelin-vector', 3 => 'javelin-dom', 4 => 'javelin-uri', ), 'c8728c70' => array( 0 => 'javelin-behavior', 1 => 'phabricator-keyboard-shortcut', 2 => 'javelin-stratcom', ), 'ca3f91eb' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-stratcom', 3 => 'phabricator-phtize', ), 'cd9e7094' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-typeahead', 3 => 'javelin-typeahead-ondemand-source', 4 => 'javelin-dom', ), 'cdde23f1' => array( 0 => 'javelin-install', 1 => 'javelin-typeahead-source', ), 'cf656c84' => array( 0 => 'javelin-behavior', 1 => 'javelin-stratcom', 2 => 'javelin-workflow', 3 => 'javelin-dom', 4 => 'javelin-fx', 5 => 'javelin-uri', 6 => 'phabricator-textareautils', ), 'cf76cfd5' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-stratcom', 3 => 'javelin-workflow', 4 => 'javelin-fx', 5 => 'javelin-util', ), 'd254d646' => array( 0 => 'javelin-util', ), 'd259e7c9' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-stratcom', 3 => 'javelin-workflow', 4 => 'javelin-util', 5 => 'phabricator-keyboard-shortcut', ), 'd4a14807' => array( 0 => 'javelin-install', 1 => 'javelin-dom', 2 => 'javelin-view', ), 'd6ca6b1c' => array( 0 => 'javelin-install', 1 => 'javelin-reactor-dom', 2 => 'javelin-view-html', 3 => 'javelin-view-interpreter', 4 => 'javelin-view-renderer', ), 'd75709e6' => array( 0 => 'javelin-behavior', 1 => 'javelin-workflow', 2 => 'javelin-json', 3 => 'javelin-dom', 4 => 'phabricator-keyboard-shortcut', ), 'd8469741' => array( 0 => 'javelin-behavior', 1 => 'javelin-typeahead-ondemand-source', 2 => 'javelin-typeahead', 3 => 'javelin-dom', 4 => 'javelin-uri', 5 => 'javelin-util', 6 => 'javelin-stratcom', ), 'd8e135db' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-util', 3 => 'javelin-stratcom', 4 => 'javelin-workflow', 5 => 'phabricator-draggable-list', ), 'd9a9b862' => array( 0 => 'javelin-install', 1 => 'javelin-util', 2 => 'javelin-stratcom', ), 'dd7e8ef5' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-workflow', 3 => 'javelin-util', 4 => 'javelin-stratcom', ), 'dddd43ac' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'phabricator-prefab', ), + 'dfd45180' => + array( + 0 => 'javelin-behavior', + 1 => 'javelin-dom', + 2 => 'javelin-util', + 3 => 'javelin-stratcom', + 4 => 'phuix-dropdown-menu', + 5 => 'phuix-action-list-view', + 6 => 'phuix-action-view', + 7 => 'phabricator-phtize', + ), 'dfdf9f34' => array( 0 => 'javelin-behavior', 1 => 'javelin-workflow', 2 => 'javelin-util', 3 => 'javelin-dom', 4 => 'javelin-stratcom', 5 => 'javelin-behavior-device', 6 => 'javelin-vector', 7 => 'javelin-router', 8 => 'phabricator-tooltip', ), 'e1ff79b1' => array( 0 => 'javelin-behavior', 1 => 'javelin-stratcom', 2 => 'javelin-dom', ), 'e5822781' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-json', 3 => 'javelin-workflow', 4 => 'javelin-magical-init', ), 'e5b406f9' => array( 0 => 'javelin-install', 1 => 'javelin-dom', 2 => 'javelin-view-visitor', 3 => 'javelin-util', ), 'e6f67523' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-request', 3 => 'javelin-util', ), 'e7c21fb3' => array( 0 => 'javelin-dom', 1 => 'javelin-util', 2 => 'javelin-stratcom', 3 => 'javelin-install', ), 'e9fdb5e5' => array( 0 => 'javelin-behavior', 1 => 'javelin-stratcom', 2 => 'javelin-util', 3 => 'javelin-dom', 4 => 'javelin-request', 5 => 'phabricator-keyboard-shortcut', ), 'ead554ec' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-stratcom', 3 => 'javelin-util', ), 'efe49472' => array( 0 => 'javelin-install', 1 => 'javelin-util', ), 'f1375ea5' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-workflow', ), 'f2441746' => array( 0 => 'javelin-dom', 1 => 'javelin-util', 2 => 'javelin-stratcom', 3 => 'javelin-install', 4 => 'javelin-request', 5 => 'javelin-workflow', ), 'f42bb8c6' => array( 0 => 'javelin-stratcom', 1 => 'javelin-behavior', 2 => 'javelin-vector', 3 => 'javelin-dom', ), 'f6555212' => array( 0 => 'javelin-install', 1 => 'javelin-reactornode', 2 => 'javelin-util', 3 => 'javelin-reactor', ), 'f7379f45' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-util', 3 => 'phabricator-shaped-request', ), 'f7f1289f' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-stratcom', ), 'f7fc67ec' => array( 0 => 'javelin-install', 1 => 'javelin-typeahead', 2 => 'javelin-dom', 3 => 'javelin-request', 4 => 'javelin-typeahead-ondemand-source', 5 => 'javelin-util', ), 'f8248bc5' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-util', 3 => 'javelin-json', 4 => 'javelin-stratcom', 5 => 'phabricator-shaped-request', ), 'fa187a68' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-util', 3 => 'javelin-stratcom', 4 => 'javelin-workflow', 5 => 'phabricator-draggable-list', ), 'fbbce3bf' => array( 0 => 'phabricator-busy', 1 => 'javelin-behavior', ), 'fe2e0ba4' => array( 0 => 'javelin-behavior', 1 => 'javelin-behavior-device', 2 => 'javelin-stratcom', 3 => 'javelin-vector', 4 => 'javelin-dom', 5 => 'javelin-magical-init', ), 'fe80fb6d' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-util', 3 => 'phabricator-prefab', 4 => 'multirow-row-manager', 5 => 'javelin-json', ), 28497740 => array( 0 => 'javelin-behavior', 1 => 'javelin-util', 2 => 'javelin-stratcom', 3 => 'javelin-dom', 4 => 'javelin-vector', 5 => 'javelin-magical-init', 6 => 'javelin-request', 7 => 'javelin-history', 8 => 'javelin-workflow', 9 => 'javelin-mask', 10 => 'javelin-behavior-device', 11 => 'phabricator-keyboard-shortcut', ), 36903077 => array( 0 => 'aphront-typeahead-control-css', ), 42126667 => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-request', ), 44524435 => array( 0 => 'javelin-install', 1 => 'javelin-dom', 2 => 'javelin-util', 3 => 'javelin-dynval', 4 => 'javelin-reactor-dom', ), 48086888 => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-workflow', ), ), 'packages' => array( 'core.pkg.css' => array( 0 => 'phabricator-core-css', 1 => 'phabricator-zindex-css', 2 => 'phui-button-css', 3 => 'phabricator-standard-page-view', 4 => 'aphront-dialog-view-css', 5 => 'phui-form-view-css', 6 => 'aphront-panel-view-css', 7 => 'aphront-table-view-css', 8 => 'aphront-tokenizer-control-css', 9 => 'aphront-typeahead-control-css', 10 => 'aphront-list-filter-view-css', 11 => 'phabricator-jump-nav', 12 => 'phabricator-remarkup-css', 13 => 'syntax-highlighting-css', 14 => 'aphront-pager-view-css', 15 => 'phabricator-transaction-view-css', 16 => 'aphront-tooltip-css', 17 => 'phabricator-flag-css', 18 => 'aphront-error-view-css', 19 => 'sprite-remarkup-css', 20 => 'sprite-gradient-css', 21 => 'sprite-menu-css', 22 => 'sprite-apps-large-css', - 23 => 'sprite-status-css', - 24 => 'phabricator-main-menu-view', - 25 => 'phabricator-notification-css', - 26 => 'phabricator-notification-menu-css', - 27 => 'lightbox-attachment-css', - 28 => 'phui-header-view-css', - 29 => 'phabricator-filetree-view-css', - 30 => 'phabricator-nav-view-css', - 31 => 'phabricator-side-menu-view-css', - 32 => 'phabricator-crumbs-view-css', - 33 => 'phui-object-item-list-view-css', - 34 => 'global-drag-and-drop-css', - 35 => 'phui-spacing-css', - 36 => 'phui-form-css', - 37 => 'phui-icon-view-css', - 38 => 'phabricator-application-launch-view-css', - 39 => 'phabricator-action-list-view-css', - 40 => 'phui-property-list-view-css', - 41 => 'phui-tag-view-css', - 42 => 'phui-list-view-css', + 23 => 'phabricator-main-menu-view', + 24 => 'phabricator-notification-css', + 25 => 'phabricator-notification-menu-css', + 26 => 'lightbox-attachment-css', + 27 => 'phui-header-view-css', + 28 => 'phabricator-filetree-view-css', + 29 => 'phabricator-nav-view-css', + 30 => 'phabricator-side-menu-view-css', + 31 => 'phabricator-crumbs-view-css', + 32 => 'phui-object-item-list-view-css', + 33 => 'global-drag-and-drop-css', + 34 => 'phui-spacing-css', + 35 => 'phui-form-css', + 36 => 'phui-icon-view-css', + 37 => 'phabricator-application-launch-view-css', + 38 => 'phabricator-action-list-view-css', + 39 => 'phui-property-list-view-css', + 40 => 'phui-tag-view-css', + 41 => 'phui-list-view-css', ), 'core.pkg.js' => array( 0 => 'javelin-behavior-aphront-basic-tokenizer', 1 => 'javelin-behavior-workflow', 2 => 'javelin-behavior-aphront-form-disable-on-submit', 3 => 'phabricator-keyboard-shortcut-manager', 4 => 'phabricator-keyboard-shortcut', 5 => 'javelin-behavior-phabricator-keyboard-shortcuts', 6 => 'javelin-behavior-refresh-csrf', 7 => 'javelin-behavior-phabricator-watch-anchor', 8 => 'javelin-behavior-phabricator-autofocus', 9 => 'phuix-dropdown-menu', 10 => 'phuix-action-list-view', 11 => 'phuix-action-view', 12 => 'phabricator-phtize', 13 => 'javelin-behavior-phabricator-oncopy', 14 => 'phabricator-tooltip', 15 => 'javelin-behavior-phabricator-tooltips', 16 => 'phabricator-prefab', 17 => 'javelin-behavior-device', 18 => 'javelin-behavior-toggle-class', 19 => 'javelin-behavior-lightbox-attachments', 20 => 'phabricator-busy', 21 => 'javelin-aphlict', 22 => 'phabricator-notification', 23 => 'javelin-behavior-aphlict-listen', 24 => 'javelin-behavior-phabricator-search-typeahead', 25 => 'javelin-behavior-konami', 26 => 'javelin-behavior-aphlict-dropdown', 27 => 'javelin-behavior-history-install', 28 => 'javelin-behavior-phabricator-gesture', 29 => 'javelin-behavior-phabricator-active-nav', 30 => 'javelin-behavior-phabricator-nav', 31 => 'javelin-behavior-phabricator-remarkup-assist', 32 => 'phabricator-textareautils', 33 => 'phabricator-file-upload', 34 => 'javelin-behavior-global-drag-and-drop', 35 => 'javelin-behavior-phabricator-reveal-content', 36 => 'phabricator-hovercard', 37 => 'javelin-behavior-phabricator-hovercards', 38 => 'javelin-color', 39 => 'javelin-fx', ), 'darkconsole.pkg.js' => array( 0 => 'javelin-behavior-dark-console', 1 => 'javelin-behavior-error-log', ), 'differential.pkg.css' => array( 0 => 'differential-core-view-css', 1 => 'differential-changeset-view-css', 2 => 'differential-results-table-css', 3 => 'differential-revision-history-css', 4 => 'differential-revision-list-css', 5 => 'differential-table-of-contents-css', 6 => 'differential-revision-comment-css', 7 => 'differential-revision-add-comment-css', 8 => 'phabricator-object-selector-css', 9 => 'phabricator-content-source-view-css', 10 => 'inline-comment-summary-css', ), 'differential.pkg.js' => array( 0 => 'phabricator-drag-and-drop-file-upload', 1 => 'phabricator-shaped-request', 2 => 'javelin-behavior-differential-feedback-preview', 3 => 'javelin-behavior-differential-edit-inline-comments', 4 => 'javelin-behavior-differential-populate', 5 => 'javelin-behavior-differential-show-more', 6 => 'javelin-behavior-differential-diff-radios', 7 => 'javelin-behavior-differential-comment-jump', 8 => 'javelin-behavior-differential-add-reviewers-and-ccs', 9 => 'javelin-behavior-differential-keyboard-navigation', 10 => 'javelin-behavior-aphront-drag-and-drop-textarea', 11 => 'javelin-behavior-phabricator-object-selector', 12 => 'javelin-behavior-repository-crossreference', 13 => 'javelin-behavior-load-blame', 14 => 'differential-inline-comment-editor', 15 => 'javelin-behavior-differential-dropdown-menus', 16 => 'javelin-behavior-differential-toggle-files', 17 => 'javelin-behavior-differential-user-select', ), 'diffusion.pkg.css' => array( 0 => 'diffusion-commit-view-css', 1 => 'diffusion-icons-css', ), 'diffusion.pkg.js' => array( 0 => 'javelin-behavior-diffusion-pull-lastmodified', 1 => 'javelin-behavior-diffusion-commit-graph', 2 => 'javelin-behavior-audit-preview', ), 'javelin.pkg.js' => array( 0 => 'javelin-util', 1 => 'javelin-install', 2 => 'javelin-event', 3 => 'javelin-stratcom', 4 => 'javelin-behavior', 5 => 'javelin-resource', 6 => 'javelin-request', 7 => 'javelin-vector', 8 => 'javelin-dom', 9 => 'javelin-json', 10 => 'javelin-uri', 11 => 'javelin-workflow', 12 => 'javelin-mask', 13 => 'javelin-typeahead', 14 => 'javelin-typeahead-normalizer', 15 => 'javelin-typeahead-source', 16 => 'javelin-typeahead-preloaded-source', 17 => 'javelin-typeahead-ondemand-source', 18 => 'javelin-tokenizer', 19 => 'javelin-history', ), 'maniphest.pkg.css' => array( 0 => 'maniphest-task-summary-css', 1 => 'phabricator-project-tag-css', ), 'maniphest.pkg.js' => array( 0 => 'javelin-behavior-maniphest-batch-selector', 1 => 'javelin-behavior-maniphest-transaction-controls', 2 => 'javelin-behavior-maniphest-transaction-preview', 3 => 'javelin-behavior-maniphest-transaction-expand', 4 => 'javelin-behavior-maniphest-subpriority-editor', ), ), ); diff --git a/resources/celerity/packages.php b/resources/celerity/packages.php index 54872d07e3..bead57c355 100644 --- a/resources/celerity/packages.php +++ b/resources/celerity/packages.php @@ -1,178 +1,177 @@ <?php return array( 'javelin.pkg.js' => array( 'javelin-util', 'javelin-install', 'javelin-event', 'javelin-stratcom', 'javelin-behavior', 'javelin-resource', 'javelin-request', 'javelin-vector', 'javelin-dom', 'javelin-json', 'javelin-uri', 'javelin-workflow', 'javelin-mask', 'javelin-typeahead', 'javelin-typeahead-normalizer', 'javelin-typeahead-source', 'javelin-typeahead-preloaded-source', 'javelin-typeahead-ondemand-source', 'javelin-tokenizer', 'javelin-history', ), 'core.pkg.js' => array( 'javelin-behavior-aphront-basic-tokenizer', 'javelin-behavior-workflow', 'javelin-behavior-aphront-form-disable-on-submit', 'phabricator-keyboard-shortcut-manager', 'phabricator-keyboard-shortcut', 'javelin-behavior-phabricator-keyboard-shortcuts', 'javelin-behavior-refresh-csrf', 'javelin-behavior-phabricator-watch-anchor', 'javelin-behavior-phabricator-autofocus', 'phuix-dropdown-menu', 'phuix-action-list-view', 'phuix-action-view', 'phabricator-phtize', 'javelin-behavior-phabricator-oncopy', 'phabricator-tooltip', 'javelin-behavior-phabricator-tooltips', 'phabricator-prefab', 'javelin-behavior-device', 'javelin-behavior-toggle-class', 'javelin-behavior-lightbox-attachments', 'phabricator-busy', 'javelin-aphlict', 'phabricator-notification', 'javelin-behavior-aphlict-listen', 'javelin-behavior-phabricator-search-typeahead', 'javelin-behavior-konami', 'javelin-behavior-aphlict-dropdown', 'javelin-behavior-history-install', 'javelin-behavior-phabricator-gesture', 'javelin-behavior-phabricator-active-nav', 'javelin-behavior-phabricator-nav', 'javelin-behavior-phabricator-remarkup-assist', 'phabricator-textareautils', 'phabricator-file-upload', 'javelin-behavior-global-drag-and-drop', 'javelin-behavior-phabricator-reveal-content', 'phabricator-hovercard', 'javelin-behavior-phabricator-hovercards', 'javelin-color', 'javelin-fx', ), 'core.pkg.css' => array( 'phabricator-core-css', 'phabricator-zindex-css', 'phui-button-css', 'phabricator-standard-page-view', 'aphront-dialog-view-css', 'phui-form-view-css', 'aphront-panel-view-css', 'aphront-table-view-css', 'aphront-tokenizer-control-css', 'aphront-typeahead-control-css', 'aphront-list-filter-view-css', 'phabricator-jump-nav', 'phabricator-remarkup-css', 'syntax-highlighting-css', 'aphront-pager-view-css', 'phabricator-transaction-view-css', 'aphront-tooltip-css', 'phabricator-flag-css', 'aphront-error-view-css', 'sprite-remarkup-css', 'sprite-gradient-css', 'sprite-menu-css', 'sprite-apps-large-css', - 'sprite-status-css', 'phabricator-main-menu-view', 'phabricator-notification-css', 'phabricator-notification-menu-css', 'lightbox-attachment-css', 'phui-header-view-css', 'phabricator-filetree-view-css', 'phabricator-nav-view-css', 'phabricator-side-menu-view-css', 'phabricator-crumbs-view-css', 'phui-object-item-list-view-css', 'global-drag-and-drop-css', 'phui-spacing-css', 'phui-form-css', 'phui-icon-view-css', 'phabricator-application-launch-view-css', 'phabricator-action-list-view-css', 'phui-property-list-view-css', 'phui-tag-view-css', 'phui-list-view-css', ), 'differential.pkg.css' => array( 'differential-core-view-css', 'differential-changeset-view-css', 'differential-results-table-css', 'differential-revision-history-css', 'differential-revision-list-css', 'differential-table-of-contents-css', 'differential-revision-comment-css', 'differential-revision-add-comment-css', 'phabricator-object-selector-css', 'phabricator-content-source-view-css', 'inline-comment-summary-css', ), 'differential.pkg.js' => array( 'phabricator-drag-and-drop-file-upload', 'phabricator-shaped-request', 'javelin-behavior-differential-feedback-preview', 'javelin-behavior-differential-edit-inline-comments', 'javelin-behavior-differential-populate', 'javelin-behavior-differential-show-more', 'javelin-behavior-differential-diff-radios', 'javelin-behavior-differential-comment-jump', 'javelin-behavior-differential-add-reviewers-and-ccs', 'javelin-behavior-differential-keyboard-navigation', 'javelin-behavior-aphront-drag-and-drop-textarea', 'javelin-behavior-phabricator-object-selector', 'javelin-behavior-repository-crossreference', 'javelin-behavior-load-blame', 'differential-inline-comment-editor', 'javelin-behavior-differential-dropdown-menus', 'javelin-behavior-differential-toggle-files', 'javelin-behavior-differential-user-select', ), 'diffusion.pkg.css' => array( 'diffusion-commit-view-css', 'diffusion-icons-css', ), 'diffusion.pkg.js' => array( 'javelin-behavior-diffusion-pull-lastmodified', 'javelin-behavior-diffusion-commit-graph', 'javelin-behavior-audit-preview', ), 'maniphest.pkg.css' => array( 'maniphest-task-summary-css', 'phabricator-project-tag-css', ), 'maniphest.pkg.js' => array( 'javelin-behavior-maniphest-batch-selector', 'javelin-behavior-maniphest-transaction-controls', 'javelin-behavior-maniphest-transaction-preview', 'javelin-behavior-maniphest-transaction-expand', 'javelin-behavior-maniphest-subpriority-editor', ), 'darkconsole.pkg.js' => array( 'javelin-behavior-dark-console', 'javelin-behavior-error-log', ), ); diff --git a/resources/sprite/manifest/status.json b/resources/sprite/manifest/status.json deleted file mode 100644 index 9cfbf11bc3..0000000000 --- a/resources/sprite/manifest/status.json +++ /dev/null @@ -1,526 +0,0 @@ -{ - "version" : 1, - "sprites" : { - "status-accept" : { - "name" : "status-accept", - "rule" : ".status-accept", - "hash" : "6493498ca9beb344cffa6211fb80cbfd" - }, - "status-accept-blue" : { - "name" : "status-accept-blue", - "rule" : ".status-accept-blue", - "hash" : "c3bde2e1361bcd7259825ecaf2d4b2ff" - }, - "status-accept-dark" : { - "name" : "status-accept-dark", - "rule" : ".status-accept-dark", - "hash" : "a2ec73e144ea598be15b8acb63f3c096" - }, - "status-accept-green" : { - "name" : "status-accept-green", - "rule" : ".status-accept-green", - "hash" : "cf0c2339a111f54adfdcc0de5c18be22" - }, - "status-accept-red" : { - "name" : "status-accept-red", - "rule" : ".status-accept-red", - "hash" : "1466a3ed72f63971e38e669715cf5b98" - }, - "status-accept-white" : { - "name" : "status-accept-white", - "rule" : ".status-accept-white", - "hash" : "8ecccf5e2ce6658d8a1e963e4be6f6e9" - }, - "status-add" : { - "name" : "status-add", - "rule" : ".status-add", - "hash" : "165d43c1451fb9ffd69c36ede87c7875" - }, - "status-add-blue" : { - "name" : "status-add-blue", - "rule" : ".status-add-blue", - "hash" : "8860efdd8f90eed700ae48595ace6b38" - }, - "status-add-dark" : { - "name" : "status-add-dark", - "rule" : ".status-add-dark", - "hash" : "38dc8634ccfe6fa30f467e97436e1a30" - }, - "status-add-green" : { - "name" : "status-add-green", - "rule" : ".status-add-green", - "hash" : "5610cd9924ad6b3461a20dd050ef4866" - }, - "status-add-red" : { - "name" : "status-add-red", - "rule" : ".status-add-red", - "hash" : "9e0abe2b6e37ef5a1a2522ad01002704" - }, - "status-add-white" : { - "name" : "status-add-white", - "rule" : ".status-add-white", - "hash" : "1a8ab412f40c569acdc709fb281fefde" - }, - "status-down" : { - "name" : "status-down", - "rule" : ".status-down", - "hash" : "85d3b2376bbed1b48cb777f07a4e244e" - }, - "status-down-blue" : { - "name" : "status-down-blue", - "rule" : ".status-down-blue", - "hash" : "25baf216cd311f321656a5f3a327c38c" - }, - "status-down-dark" : { - "name" : "status-down-dark", - "rule" : ".status-down-dark", - "hash" : "bb82d18b729ac30956200b655eafeeb8" - }, - "status-down-green" : { - "name" : "status-down-green", - "rule" : ".status-down-green", - "hash" : "c29ad19910664ecc94e0d1fa99a0a6c0" - }, - "status-down-red" : { - "name" : "status-down-red", - "rule" : ".status-down-red", - "hash" : "644f0d38cad5cc6797fe81ed30b9bc6a" - }, - "status-down-white" : { - "name" : "status-down-white", - "rule" : ".status-down-white", - "hash" : "5bc0af6641ef545218ecced2d25e9a10" - }, - "status-info" : { - "name" : "status-info", - "rule" : ".status-info", - "hash" : "3b9d6abe2fb44b0959208632a77d3582" - }, - "status-info-blue" : { - "name" : "status-info-blue", - "rule" : ".status-info-blue", - "hash" : "2acc8c62d8963bec9ce632de60a4da41" - }, - "status-info-dark" : { - "name" : "status-info-dark", - "rule" : ".status-info-dark", - "hash" : "d96f44c17e67d7c0c10a400e6ff294f1" - }, - "status-info-green" : { - "name" : "status-info-green", - "rule" : ".status-info-green", - "hash" : "28fc83a1f5bee4ac39a0dcd52e180818" - }, - "status-info-red" : { - "name" : "status-info-red", - "rule" : ".status-info-red", - "hash" : "fc26e5509140d8e9a3305a39c44773f0" - }, - "status-info-white" : { - "name" : "status-info-white", - "rule" : ".status-info-white", - "hash" : "b70025f459685371f8397b61944bef7d" - }, - "status-left" : { - "name" : "status-left", - "rule" : ".status-left", - "hash" : "4649139ffc7e668b67d6978bbd5cbf15" - }, - "status-left-blue" : { - "name" : "status-left-blue", - "rule" : ".status-left-blue", - "hash" : "cdec5d2617cb7fcfbfea336881d267f0" - }, - "status-left-dark" : { - "name" : "status-left-dark", - "rule" : ".status-left-dark", - "hash" : "83b58d1cde130deb01971888ad0bcfc1" - }, - "status-left-green" : { - "name" : "status-left-green", - "rule" : ".status-left-green", - "hash" : "6b34445f1a034e71432a5823bed1c4d7" - }, - "status-left-red" : { - "name" : "status-left-red", - "rule" : ".status-left-red", - "hash" : "38ebb75c0fbcf6fe96def6c2ab70b343" - }, - "status-left-white" : { - "name" : "status-left-white", - "rule" : ".status-left-white", - "hash" : "9e89400271b55590e610188d93671934" - }, - "status-minus" : { - "name" : "status-minus", - "rule" : ".status-minus", - "hash" : "a232bd27513a71ce8f4cd163d8aa05cf" - }, - "status-minus-blue" : { - "name" : "status-minus-blue", - "rule" : ".status-minus-blue", - "hash" : "61ef81a9b78b4de4bf6303f8d51c86ef" - }, - "status-minus-dark" : { - "name" : "status-minus-dark", - "rule" : ".status-minus-dark", - "hash" : "db4ddb69a22c7f6f09669fe3c488c4f0" - }, - "status-minus-green" : { - "name" : "status-minus-green", - "rule" : ".status-minus-green", - "hash" : "9e5402f65601ced38a967d4e17b80f1c" - }, - "status-minus-red" : { - "name" : "status-minus-red", - "rule" : ".status-minus-red", - "hash" : "bcaf148bc842e398f08d8c01506bd5b6" - }, - "status-minus-white" : { - "name" : "status-minus-white", - "rule" : ".status-minus-white", - "hash" : "c5a3771452dda603fbaee87371044f5a" - }, - "status-oh-closed" : { - "name" : "status-oh-closed", - "rule" : ".status-oh-closed", - "hash" : "fa5f2ef65de3e55c9251aebbed662f7a" - }, - "status-oh-closed-dark" : { - "name" : "status-oh-closed-dark", - "rule" : ".status-oh-closed-dark", - "hash" : "926d6a4e9530a20cd9cd655b334e4f89" - }, - "status-oh-ok" : { - "name" : "status-oh-ok", - "rule" : ".status-oh-ok", - "hash" : "0d1a2962da8fa12dd41a11316ba7f2eb" - }, - "status-oh-ok-dark" : { - "name" : "status-oh-ok-dark", - "rule" : ".status-oh-ok-dark", - "hash" : "2daa23d9b1b6c66daac93625dbd26dbc" - }, - "status-oh-open" : { - "name" : "status-oh-open", - "rule" : ".status-oh-open", - "hash" : "8d759391597ad3925abf2b4b4aaed537" - }, - "status-oh-open-green" : { - "name" : "status-oh-open-green", - "rule" : ".status-oh-open-green", - "hash" : "18fbeb777a9c5a7d46e0ba0760d3a557" - }, - "status-oh-open-red" : { - "name" : "status-oh-open-red", - "rule" : ".status-oh-open-red", - "hash" : "982610ba3d0bad1aaa11dcd3b593adbf" - }, - "status-open" : { - "name" : "status-open", - "rule" : ".status-open", - "hash" : "5b6b67382052982358d0047f07dd0424" - }, - "status-open-blue" : { - "name" : "status-open-blue", - "rule" : ".status-open-blue", - "hash" : "9632bb52d5f24941202848c2e3d4488a" - }, - "status-open-dark" : { - "name" : "status-open-dark", - "rule" : ".status-open-dark", - "hash" : "ca38ff5fc8a327d96cd1bbc23043fbb4" - }, - "status-open-green" : { - "name" : "status-open-green", - "rule" : ".status-open-green", - "hash" : "b4a2c17594a5301e2bd52a9df71819d3" - }, - "status-open-red" : { - "name" : "status-open-red", - "rule" : ".status-open-red", - "hash" : "f92b1544978d691da6912f937df54273" - }, - "status-open-white" : { - "name" : "status-open-white", - "rule" : ".status-open-white", - "hash" : "169dc0e8f36444ea30163181f9c88dc2" - }, - "status-pl-summary" : { - "name" : "status-pl-summary", - "rule" : ".status-pl-summary", - "hash" : "0abd0eab8617fb88f9b8f4d2f00e17b8" - }, - "status-pl-testplan" : { - "name" : "status-pl-testplan", - "rule" : ".status-pl-testplan", - "hash" : "03dbb3c53bfddfb553d49c6f27a76765" - }, - "status-policy-admin" : { - "name" : "status-policy-admin", - "rule" : ".status-policy-admin", - "hash" : "16c86a605a15a7a87f4d706c2122834c" - }, - "status-policy-admin-white" : { - "name" : "status-policy-admin-white", - "rule" : ".status-policy-admin-white, .phuix-dropdown-menu .phabricator-action-view:hover .status-policy-admin", - "hash" : "4b16ec5170bc30fb688f7e086e61a7f1" - }, - "status-policy-all" : { - "name" : "status-policy-all", - "rule" : ".status-policy-all", - "hash" : "7e8f9e8019ad7f668e51a097f0554ace" - }, - "status-policy-all-white" : { - "name" : "status-policy-all-white", - "rule" : ".status-policy-all-white, .phuix-dropdown-menu .phabricator-action-view:hover .status-policy-all", - "hash" : "24ed12bf6f58c21a82be125ace2ff0d0" - }, - "status-policy-custom" : { - "name" : "status-policy-custom", - "rule" : ".status-policy-custom", - "hash" : "3cf516b1e50412ec95594b9866ab1c39" - }, - "status-policy-custom-white" : { - "name" : "status-policy-custom-white", - "rule" : ".status-policy-custom-white, .phuix-dropdown-menu .phabricator-action-view:hover .status-policy-custom", - "hash" : "ff8b4cbe21f3b4254f343fffc170ef4b" - }, - "status-policy-elist" : { - "name" : "status-policy-elist", - "rule" : ".status-policy-elist", - "hash" : "da03d710291f394933260dbf43dbc654" - }, - "status-policy-elist-white" : { - "name" : "status-policy-elist-white", - "rule" : ".status-policy-elist-white", - "hash" : "57e90e9c91fd640e6a778ddc9a2fa015" - }, - "status-policy-noone" : { - "name" : "status-policy-noone", - "rule" : ".status-policy-noone", - "hash" : "e3403fb78718660105d86029518cf43c" - }, - "status-policy-noone-white" : { - "name" : "status-policy-noone-white", - "rule" : ".status-policy-noone-white, .phuix-dropdown-menu .phabricator-action-view:hover .status-policy-noone", - "hash" : "80fb9b153fec4d8136242c5ddc2d8e77" - }, - "status-policy-project" : { - "name" : "status-policy-project", - "rule" : ".status-policy-project", - "hash" : "2b77235f7057f3b29075d153345eacc6" - }, - "status-policy-project-white" : { - "name" : "status-policy-project-white", - "rule" : ".status-policy-project-white, .phuix-dropdown-menu .phabricator-action-view:hover .status-policy-project", - "hash" : "ac2b6f19edb8d6c40f0bcb3fd477a067" - }, - "status-policy-public" : { - "name" : "status-policy-public", - "rule" : ".status-policy-public", - "hash" : "e7959890117091fb185816dbc888dfd2" - }, - "status-policy-public-white" : { - "name" : "status-policy-public-white", - "rule" : ".status-policy-public-white, .phuix-dropdown-menu .phabricator-action-view:hover .status-policy-public", - "hash" : "cf809ca49eefed5375c2ea081e721971" - }, - "status-policy-unknown" : { - "name" : "status-policy-unknown", - "rule" : ".status-policy-unknown", - "hash" : "0235fd879547c98ad658fa0375c386b6" - }, - "status-policy-unknown-white" : { - "name" : "status-policy-unknown-white", - "rule" : ".status-policy-unknown-white, .phuix-dropdown-menu .phabricator-action-view:hover .status-policy-unknown", - "hash" : "98985bfa005672c4b88feaf88cfa72bc" - }, - "status-policy-user" : { - "name" : "status-policy-user", - "rule" : ".status-policy-user", - "hash" : "6c21aa20866d5b86f074bdcf4f487d40" - }, - "status-policy-user-white" : { - "name" : "status-policy-user-white", - "rule" : ".status-policy-user-white", - "hash" : "97a569e973df3f1e4fe012adf216ca40" - }, - "status-question" : { - "name" : "status-question", - "rule" : ".status-question", - "hash" : "f7290c6ba78eb37a6641eecfdc128f08" - }, - "status-question-blue" : { - "name" : "status-question-blue", - "rule" : ".status-question-blue", - "hash" : "44ebbdbe059ca77ae4dc6a6b98de1ccf" - }, - "status-question-dark" : { - "name" : "status-question-dark", - "rule" : ".status-question-dark", - "hash" : "5fdd5f2b089f4481a39760a50224d8b2" - }, - "status-question-green" : { - "name" : "status-question-green", - "rule" : ".status-question-green", - "hash" : "326dfc6c1841410ce0f22d702c872c01" - }, - "status-question-red" : { - "name" : "status-question-red", - "rule" : ".status-question-red", - "hash" : "18dbec41627f8c047c4e736f84dacb33" - }, - "status-question-white" : { - "name" : "status-question-white", - "rule" : ".status-question-white", - "hash" : "5e7f546f978d1d0545cad127ea3bcf80" - }, - "status-reject" : { - "name" : "status-reject", - "rule" : ".status-reject", - "hash" : "288489e716b390c5404969f9979b9ded" - }, - "status-reject-blue" : { - "name" : "status-reject-blue", - "rule" : ".status-reject-blue", - "hash" : "b0f51db6aa6ee85a24a1f4c13812d7ef" - }, - "status-reject-dark" : { - "name" : "status-reject-dark", - "rule" : ".status-reject-dark", - "hash" : "9b28c36f6cbd6d5d5731b971193a151e" - }, - "status-reject-green" : { - "name" : "status-reject-green", - "rule" : ".status-reject-green", - "hash" : "fc171843df97bcdc6e4679682b3b31e4" - }, - "status-reject-red" : { - "name" : "status-reject-red", - "rule" : ".status-reject-red", - "hash" : "6de0dd95a92d33bda228aaa9ba6deee5" - }, - "status-reject-white" : { - "name" : "status-reject-white", - "rule" : ".status-reject-white", - "hash" : "e709a3fb3081a395900deaef0591066c" - }, - "status-right" : { - "name" : "status-right", - "rule" : ".status-right", - "hash" : "cd61a821b88b7c76a43d7f405d54b6cc" - }, - "status-right-blue" : { - "name" : "status-right-blue", - "rule" : ".status-right-blue", - "hash" : "ca1cae1d93486785ec50458ba3b19082" - }, - "status-right-dark" : { - "name" : "status-right-dark", - "rule" : ".status-right-dark", - "hash" : "fb6600fd1775a8a4fb85709dc4f6c28c" - }, - "status-right-green" : { - "name" : "status-right-green", - "rule" : ".status-right-green", - "hash" : "9a52218e6c6d3968a05eb51865ed3cba" - }, - "status-right-red" : { - "name" : "status-right-red", - "rule" : ".status-right-red", - "hash" : "06bd9747ce4cc87282b2fb207c525f0c" - }, - "status-right-white" : { - "name" : "status-right-white", - "rule" : ".status-right-white", - "hash" : "be2ffb65a7799cd9a5e00c2334e378b2" - }, - "status-time-green" : { - "name" : "status-time-green", - "rule" : ".status-time-green", - "hash" : "5cb4771e10aaf79ac490bc93bd029d8f" - }, - "status-time-orange" : { - "name" : "status-time-orange", - "rule" : ".status-time-orange", - "hash" : "aa48043beff2c8576402dbccbe4ad3e2" - }, - "status-time-red" : { - "name" : "status-time-red", - "rule" : ".status-time-red", - "hash" : "e4dbf14f1ac16338b5e01aa04f2e267e" - }, - "status-time-yellow" : { - "name" : "status-time-yellow", - "rule" : ".status-time-yellow", - "hash" : "79756bcf7f2401d7e3a97ff03b981dcb" - }, - "status-up" : { - "name" : "status-up", - "rule" : ".status-up", - "hash" : "d42ac0a3f7bbae3bf57478f533ae88f4" - }, - "status-up-blue" : { - "name" : "status-up-blue", - "rule" : ".status-up-blue", - "hash" : "44fc24b3646e29c949b639157c315140" - }, - "status-up-dark" : { - "name" : "status-up-dark", - "rule" : ".status-up-dark", - "hash" : "459ed916291bfa905676ae0818bb2e1b" - }, - "status-up-green" : { - "name" : "status-up-green", - "rule" : ".status-up-green", - "hash" : "6a682e48fc2f240b19bd175be52c9256" - }, - "status-up-red" : { - "name" : "status-up-red", - "rule" : ".status-up-red", - "hash" : "0e38f6282e542470ecb68e55fad7eb76" - }, - "status-up-white" : { - "name" : "status-up-white", - "rule" : ".status-up-white", - "hash" : "ce80e291bc905b2692ad9f3ece7cf206" - }, - "status-warning" : { - "name" : "status-warning", - "rule" : ".status-warning", - "hash" : "425a02c06f9590e9f7c078badf832d0c" - }, - "status-warning-blue" : { - "name" : "status-warning-blue", - "rule" : ".status-warning-blue", - "hash" : "93f5e066a01a874adc2c120cca4bd1fc" - }, - "status-warning-dark" : { - "name" : "status-warning-dark", - "rule" : ".status-warning-dark", - "hash" : "273a519299d7063710452d21c0bc6406" - }, - "status-warning-green" : { - "name" : "status-warning-green", - "rule" : ".status-warning-green", - "hash" : "991514e5b75509b27fd68d21755b9fa6" - }, - "status-warning-red" : { - "name" : "status-warning-red", - "rule" : ".status-warning-red", - "hash" : "b15f61f314cbda5486d3aa21990153ae" - }, - "status-warning-white" : { - "name" : "status-warning-white", - "rule" : ".status-warning-white", - "hash" : "62ff8f6bf696e58f71eb4e1c6fe9b2e1" - } - }, - "scales" : [ - 1, - 2 - ], - "header" : "\/**\n * @provides sprite-status-css\n * @generated\n *\/\n\n.sprite-status {\n background-image: url(\/rsrc\/image\/sprite-status.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-status {\n background-image: url(\/rsrc\/image\/sprite-status-X2.png);\n background-size: {X}px {Y}px;\n }\n}\n", - "type" : "standard" -} diff --git a/resources/sprite/status_1x/accept-blue.png b/resources/sprite/status_1x/accept-blue.png deleted file mode 100644 index c5aaaee5e7..0000000000 Binary files a/resources/sprite/status_1x/accept-blue.png and /dev/null differ diff --git a/resources/sprite/status_1x/accept-dark.png b/resources/sprite/status_1x/accept-dark.png deleted file mode 100644 index d9da80853e..0000000000 Binary files a/resources/sprite/status_1x/accept-dark.png and /dev/null differ diff --git a/resources/sprite/status_1x/accept-green.png b/resources/sprite/status_1x/accept-green.png deleted file mode 100644 index bc77971ab0..0000000000 Binary files a/resources/sprite/status_1x/accept-green.png and /dev/null differ diff --git a/resources/sprite/status_1x/accept-red.png b/resources/sprite/status_1x/accept-red.png deleted file mode 100644 index c9ffd1fbf9..0000000000 Binary files a/resources/sprite/status_1x/accept-red.png and /dev/null differ diff --git a/resources/sprite/status_1x/accept-white.png b/resources/sprite/status_1x/accept-white.png deleted file mode 100644 index baf7373e55..0000000000 Binary files a/resources/sprite/status_1x/accept-white.png and /dev/null differ diff --git a/resources/sprite/status_1x/accept.png b/resources/sprite/status_1x/accept.png deleted file mode 100644 index d6b555762c..0000000000 Binary files a/resources/sprite/status_1x/accept.png and /dev/null differ diff --git a/resources/sprite/status_1x/add-blue.png b/resources/sprite/status_1x/add-blue.png deleted file mode 100644 index f71e265f56..0000000000 Binary files a/resources/sprite/status_1x/add-blue.png and /dev/null differ diff --git a/resources/sprite/status_1x/add-dark.png b/resources/sprite/status_1x/add-dark.png deleted file mode 100644 index 8a1d1125b0..0000000000 Binary files a/resources/sprite/status_1x/add-dark.png and /dev/null differ diff --git a/resources/sprite/status_1x/add-green.png b/resources/sprite/status_1x/add-green.png deleted file mode 100644 index 423d9914a0..0000000000 Binary files a/resources/sprite/status_1x/add-green.png and /dev/null differ diff --git a/resources/sprite/status_1x/add-red.png b/resources/sprite/status_1x/add-red.png deleted file mode 100644 index 6ba9509074..0000000000 Binary files a/resources/sprite/status_1x/add-red.png and /dev/null differ diff --git a/resources/sprite/status_1x/add-white.png b/resources/sprite/status_1x/add-white.png deleted file mode 100644 index 00907c2434..0000000000 Binary files a/resources/sprite/status_1x/add-white.png and /dev/null differ diff --git a/resources/sprite/status_1x/add.png b/resources/sprite/status_1x/add.png deleted file mode 100644 index 1aabe0fdc7..0000000000 Binary files a/resources/sprite/status_1x/add.png and /dev/null differ diff --git a/resources/sprite/status_1x/down-blue.png b/resources/sprite/status_1x/down-blue.png deleted file mode 100644 index 7694510ab2..0000000000 Binary files a/resources/sprite/status_1x/down-blue.png and /dev/null differ diff --git a/resources/sprite/status_1x/down-dark.png b/resources/sprite/status_1x/down-dark.png deleted file mode 100644 index 0266a88261..0000000000 Binary files a/resources/sprite/status_1x/down-dark.png and /dev/null differ diff --git a/resources/sprite/status_1x/down-green.png b/resources/sprite/status_1x/down-green.png deleted file mode 100644 index 44eee1688b..0000000000 Binary files a/resources/sprite/status_1x/down-green.png and /dev/null differ diff --git a/resources/sprite/status_1x/down-red.png b/resources/sprite/status_1x/down-red.png deleted file mode 100644 index 019699cc9e..0000000000 Binary files a/resources/sprite/status_1x/down-red.png and /dev/null differ diff --git a/resources/sprite/status_1x/down-white.png b/resources/sprite/status_1x/down-white.png deleted file mode 100644 index 8aa0498bfc..0000000000 Binary files a/resources/sprite/status_1x/down-white.png and /dev/null differ diff --git a/resources/sprite/status_1x/down.png b/resources/sprite/status_1x/down.png deleted file mode 100644 index 468758b917..0000000000 Binary files a/resources/sprite/status_1x/down.png and /dev/null differ diff --git a/resources/sprite/status_1x/info-blue.png b/resources/sprite/status_1x/info-blue.png deleted file mode 100644 index c8d614ffde..0000000000 Binary files a/resources/sprite/status_1x/info-blue.png and /dev/null differ diff --git a/resources/sprite/status_1x/info-dark.png b/resources/sprite/status_1x/info-dark.png deleted file mode 100644 index d4a73ec2d4..0000000000 Binary files a/resources/sprite/status_1x/info-dark.png and /dev/null differ diff --git a/resources/sprite/status_1x/info-green.png b/resources/sprite/status_1x/info-green.png deleted file mode 100644 index 8ae658a401..0000000000 Binary files a/resources/sprite/status_1x/info-green.png and /dev/null differ diff --git a/resources/sprite/status_1x/info-red.png b/resources/sprite/status_1x/info-red.png deleted file mode 100644 index 61125d0eab..0000000000 Binary files a/resources/sprite/status_1x/info-red.png and /dev/null differ diff --git a/resources/sprite/status_1x/info-white.png b/resources/sprite/status_1x/info-white.png deleted file mode 100644 index e3e3a05b76..0000000000 Binary files a/resources/sprite/status_1x/info-white.png and /dev/null differ diff --git a/resources/sprite/status_1x/info.png b/resources/sprite/status_1x/info.png deleted file mode 100644 index 74f979b30b..0000000000 Binary files a/resources/sprite/status_1x/info.png and /dev/null differ diff --git a/resources/sprite/status_1x/left-blue.png b/resources/sprite/status_1x/left-blue.png deleted file mode 100644 index c3c3fe15d3..0000000000 Binary files a/resources/sprite/status_1x/left-blue.png and /dev/null differ diff --git a/resources/sprite/status_1x/left-dark.png b/resources/sprite/status_1x/left-dark.png deleted file mode 100644 index 445d678c7d..0000000000 Binary files a/resources/sprite/status_1x/left-dark.png and /dev/null differ diff --git a/resources/sprite/status_1x/left-green.png b/resources/sprite/status_1x/left-green.png deleted file mode 100644 index 389f94a260..0000000000 Binary files a/resources/sprite/status_1x/left-green.png and /dev/null differ diff --git a/resources/sprite/status_1x/left-red.png b/resources/sprite/status_1x/left-red.png deleted file mode 100644 index d9556fed8d..0000000000 Binary files a/resources/sprite/status_1x/left-red.png and /dev/null differ diff --git a/resources/sprite/status_1x/left-white.png b/resources/sprite/status_1x/left-white.png deleted file mode 100644 index c02ae7a57b..0000000000 Binary files a/resources/sprite/status_1x/left-white.png and /dev/null differ diff --git a/resources/sprite/status_1x/left.png b/resources/sprite/status_1x/left.png deleted file mode 100644 index 70d914dc2c..0000000000 Binary files a/resources/sprite/status_1x/left.png and /dev/null differ diff --git a/resources/sprite/status_1x/minus-blue.png b/resources/sprite/status_1x/minus-blue.png deleted file mode 100644 index 7c45c6a42c..0000000000 Binary files a/resources/sprite/status_1x/minus-blue.png and /dev/null differ diff --git a/resources/sprite/status_1x/minus-dark.png b/resources/sprite/status_1x/minus-dark.png deleted file mode 100644 index e23ec95946..0000000000 Binary files a/resources/sprite/status_1x/minus-dark.png and /dev/null differ diff --git a/resources/sprite/status_1x/minus-green.png b/resources/sprite/status_1x/minus-green.png deleted file mode 100644 index 9245c2c0b9..0000000000 Binary files a/resources/sprite/status_1x/minus-green.png and /dev/null differ diff --git a/resources/sprite/status_1x/minus-red.png b/resources/sprite/status_1x/minus-red.png deleted file mode 100644 index 0b2838ae98..0000000000 Binary files a/resources/sprite/status_1x/minus-red.png and /dev/null differ diff --git a/resources/sprite/status_1x/minus-white.png b/resources/sprite/status_1x/minus-white.png deleted file mode 100644 index f806c33e7a..0000000000 Binary files a/resources/sprite/status_1x/minus-white.png and /dev/null differ diff --git a/resources/sprite/status_1x/minus.png b/resources/sprite/status_1x/minus.png deleted file mode 100644 index 7494e59e41..0000000000 Binary files a/resources/sprite/status_1x/minus.png and /dev/null differ diff --git a/resources/sprite/status_1x/oh-closed-dark.png b/resources/sprite/status_1x/oh-closed-dark.png deleted file mode 100644 index a0c94e1ccc..0000000000 Binary files a/resources/sprite/status_1x/oh-closed-dark.png and /dev/null differ diff --git a/resources/sprite/status_1x/oh-closed.png b/resources/sprite/status_1x/oh-closed.png deleted file mode 100644 index 830c8c354b..0000000000 Binary files a/resources/sprite/status_1x/oh-closed.png and /dev/null differ diff --git a/resources/sprite/status_1x/oh-ok-dark.png b/resources/sprite/status_1x/oh-ok-dark.png deleted file mode 100644 index ec25388c21..0000000000 Binary files a/resources/sprite/status_1x/oh-ok-dark.png and /dev/null differ diff --git a/resources/sprite/status_1x/oh-ok.png b/resources/sprite/status_1x/oh-ok.png deleted file mode 100644 index d2ff96e2b6..0000000000 Binary files a/resources/sprite/status_1x/oh-ok.png and /dev/null differ diff --git a/resources/sprite/status_1x/oh-open-green.png b/resources/sprite/status_1x/oh-open-green.png deleted file mode 100644 index 7b7c57a9fb..0000000000 Binary files a/resources/sprite/status_1x/oh-open-green.png and /dev/null differ diff --git a/resources/sprite/status_1x/oh-open-red.png b/resources/sprite/status_1x/oh-open-red.png deleted file mode 100644 index 7bfa8ea0bb..0000000000 Binary files a/resources/sprite/status_1x/oh-open-red.png and /dev/null differ diff --git a/resources/sprite/status_1x/oh-open.png b/resources/sprite/status_1x/oh-open.png deleted file mode 100644 index 8422beb768..0000000000 Binary files a/resources/sprite/status_1x/oh-open.png and /dev/null differ diff --git a/resources/sprite/status_1x/open-blue.png b/resources/sprite/status_1x/open-blue.png deleted file mode 100644 index 0dc1658f0c..0000000000 Binary files a/resources/sprite/status_1x/open-blue.png and /dev/null differ diff --git a/resources/sprite/status_1x/open-dark.png b/resources/sprite/status_1x/open-dark.png deleted file mode 100644 index 6a03b21ecc..0000000000 Binary files a/resources/sprite/status_1x/open-dark.png and /dev/null differ diff --git a/resources/sprite/status_1x/open-green.png b/resources/sprite/status_1x/open-green.png deleted file mode 100644 index a9e09e71cc..0000000000 Binary files a/resources/sprite/status_1x/open-green.png and /dev/null differ diff --git a/resources/sprite/status_1x/open-red.png b/resources/sprite/status_1x/open-red.png deleted file mode 100644 index c45f11f247..0000000000 Binary files a/resources/sprite/status_1x/open-red.png and /dev/null differ diff --git a/resources/sprite/status_1x/open-white.png b/resources/sprite/status_1x/open-white.png deleted file mode 100644 index 8bd1d357b0..0000000000 Binary files a/resources/sprite/status_1x/open-white.png and /dev/null differ diff --git a/resources/sprite/status_1x/open.png b/resources/sprite/status_1x/open.png deleted file mode 100644 index 1dfc7e1515..0000000000 Binary files a/resources/sprite/status_1x/open.png and /dev/null differ diff --git a/resources/sprite/status_1x/pl-summary.png b/resources/sprite/status_1x/pl-summary.png deleted file mode 100644 index b2274ae85e..0000000000 Binary files a/resources/sprite/status_1x/pl-summary.png and /dev/null differ diff --git a/resources/sprite/status_1x/pl-testplan.png b/resources/sprite/status_1x/pl-testplan.png deleted file mode 100644 index 22ad223bef..0000000000 Binary files a/resources/sprite/status_1x/pl-testplan.png and /dev/null differ diff --git a/resources/sprite/status_1x/policy-admin-white.png b/resources/sprite/status_1x/policy-admin-white.png deleted file mode 100644 index 48b9624c0d..0000000000 Binary files a/resources/sprite/status_1x/policy-admin-white.png and /dev/null differ diff --git a/resources/sprite/status_1x/policy-admin.png b/resources/sprite/status_1x/policy-admin.png deleted file mode 100644 index fed46ed926..0000000000 Binary files a/resources/sprite/status_1x/policy-admin.png and /dev/null differ diff --git a/resources/sprite/status_1x/policy-all-white.png b/resources/sprite/status_1x/policy-all-white.png deleted file mode 100644 index e84b9efebc..0000000000 Binary files a/resources/sprite/status_1x/policy-all-white.png and /dev/null differ diff --git a/resources/sprite/status_1x/policy-all.png b/resources/sprite/status_1x/policy-all.png deleted file mode 100644 index 6a569525b7..0000000000 Binary files a/resources/sprite/status_1x/policy-all.png and /dev/null differ diff --git a/resources/sprite/status_1x/policy-custom-white.png b/resources/sprite/status_1x/policy-custom-white.png deleted file mode 100644 index 909c69ce86..0000000000 Binary files a/resources/sprite/status_1x/policy-custom-white.png and /dev/null differ diff --git a/resources/sprite/status_1x/policy-custom.png b/resources/sprite/status_1x/policy-custom.png deleted file mode 100644 index bc707edafe..0000000000 Binary files a/resources/sprite/status_1x/policy-custom.png and /dev/null differ diff --git a/resources/sprite/status_1x/policy-elist-white.png b/resources/sprite/status_1x/policy-elist-white.png deleted file mode 100644 index 1d28e6c28f..0000000000 Binary files a/resources/sprite/status_1x/policy-elist-white.png and /dev/null differ diff --git a/resources/sprite/status_1x/policy-elist.png b/resources/sprite/status_1x/policy-elist.png deleted file mode 100644 index 384482fc79..0000000000 Binary files a/resources/sprite/status_1x/policy-elist.png and /dev/null differ diff --git a/resources/sprite/status_1x/policy-noone-white.png b/resources/sprite/status_1x/policy-noone-white.png deleted file mode 100644 index 8e89ad3c46..0000000000 Binary files a/resources/sprite/status_1x/policy-noone-white.png and /dev/null differ diff --git a/resources/sprite/status_1x/policy-noone.png b/resources/sprite/status_1x/policy-noone.png deleted file mode 100644 index e018714976..0000000000 Binary files a/resources/sprite/status_1x/policy-noone.png and /dev/null differ diff --git a/resources/sprite/status_1x/policy-project-white.png b/resources/sprite/status_1x/policy-project-white.png deleted file mode 100644 index 4e39cc3ab5..0000000000 Binary files a/resources/sprite/status_1x/policy-project-white.png and /dev/null differ diff --git a/resources/sprite/status_1x/policy-project.png b/resources/sprite/status_1x/policy-project.png deleted file mode 100644 index 8d9582d3d0..0000000000 Binary files a/resources/sprite/status_1x/policy-project.png and /dev/null differ diff --git a/resources/sprite/status_1x/policy-public-white.png b/resources/sprite/status_1x/policy-public-white.png deleted file mode 100644 index 5bc2f31947..0000000000 Binary files a/resources/sprite/status_1x/policy-public-white.png and /dev/null differ diff --git a/resources/sprite/status_1x/policy-public.png b/resources/sprite/status_1x/policy-public.png deleted file mode 100644 index c54f47a7cd..0000000000 Binary files a/resources/sprite/status_1x/policy-public.png and /dev/null differ diff --git a/resources/sprite/status_1x/policy-unknown-white.png b/resources/sprite/status_1x/policy-unknown-white.png deleted file mode 100644 index 28398a7b47..0000000000 Binary files a/resources/sprite/status_1x/policy-unknown-white.png and /dev/null differ diff --git a/resources/sprite/status_1x/policy-unknown.png b/resources/sprite/status_1x/policy-unknown.png deleted file mode 100644 index b415a2466f..0000000000 Binary files a/resources/sprite/status_1x/policy-unknown.png and /dev/null differ diff --git a/resources/sprite/status_1x/policy-user-white.png b/resources/sprite/status_1x/policy-user-white.png deleted file mode 100644 index 2b4ae43457..0000000000 Binary files a/resources/sprite/status_1x/policy-user-white.png and /dev/null differ diff --git a/resources/sprite/status_1x/policy-user.png b/resources/sprite/status_1x/policy-user.png deleted file mode 100644 index 1a33858470..0000000000 Binary files a/resources/sprite/status_1x/policy-user.png and /dev/null differ diff --git a/resources/sprite/status_1x/question-blue.png b/resources/sprite/status_1x/question-blue.png deleted file mode 100644 index bc2fe4a772..0000000000 Binary files a/resources/sprite/status_1x/question-blue.png and /dev/null differ diff --git a/resources/sprite/status_1x/question-dark.png b/resources/sprite/status_1x/question-dark.png deleted file mode 100644 index 5a77cebe3f..0000000000 Binary files a/resources/sprite/status_1x/question-dark.png and /dev/null differ diff --git a/resources/sprite/status_1x/question-green.png b/resources/sprite/status_1x/question-green.png deleted file mode 100644 index 9f34c1841c..0000000000 Binary files a/resources/sprite/status_1x/question-green.png and /dev/null differ diff --git a/resources/sprite/status_1x/question-red.png b/resources/sprite/status_1x/question-red.png deleted file mode 100644 index ff11aae3cc..0000000000 Binary files a/resources/sprite/status_1x/question-red.png and /dev/null differ diff --git a/resources/sprite/status_1x/question-white.png b/resources/sprite/status_1x/question-white.png deleted file mode 100644 index 216e3a5886..0000000000 Binary files a/resources/sprite/status_1x/question-white.png and /dev/null differ diff --git a/resources/sprite/status_1x/question.png b/resources/sprite/status_1x/question.png deleted file mode 100644 index f0f9af275f..0000000000 Binary files a/resources/sprite/status_1x/question.png and /dev/null differ diff --git a/resources/sprite/status_1x/reject-blue.png b/resources/sprite/status_1x/reject-blue.png deleted file mode 100644 index f897017977..0000000000 Binary files a/resources/sprite/status_1x/reject-blue.png and /dev/null differ diff --git a/resources/sprite/status_1x/reject-dark.png b/resources/sprite/status_1x/reject-dark.png deleted file mode 100644 index ad504aa387..0000000000 Binary files a/resources/sprite/status_1x/reject-dark.png and /dev/null differ diff --git a/resources/sprite/status_1x/reject-green.png b/resources/sprite/status_1x/reject-green.png deleted file mode 100644 index ad76e62db2..0000000000 Binary files a/resources/sprite/status_1x/reject-green.png and /dev/null differ diff --git a/resources/sprite/status_1x/reject-red.png b/resources/sprite/status_1x/reject-red.png deleted file mode 100644 index 9105004062..0000000000 Binary files a/resources/sprite/status_1x/reject-red.png and /dev/null differ diff --git a/resources/sprite/status_1x/reject-white.png b/resources/sprite/status_1x/reject-white.png deleted file mode 100644 index 0caf704258..0000000000 Binary files a/resources/sprite/status_1x/reject-white.png and /dev/null differ diff --git a/resources/sprite/status_1x/reject.png b/resources/sprite/status_1x/reject.png deleted file mode 100644 index 6c534a58dc..0000000000 Binary files a/resources/sprite/status_1x/reject.png and /dev/null differ diff --git a/resources/sprite/status_1x/right-blue.png b/resources/sprite/status_1x/right-blue.png deleted file mode 100644 index 71529b7504..0000000000 Binary files a/resources/sprite/status_1x/right-blue.png and /dev/null differ diff --git a/resources/sprite/status_1x/right-dark.png b/resources/sprite/status_1x/right-dark.png deleted file mode 100644 index bb13cf6512..0000000000 Binary files a/resources/sprite/status_1x/right-dark.png and /dev/null differ diff --git a/resources/sprite/status_1x/right-green.png b/resources/sprite/status_1x/right-green.png deleted file mode 100644 index fe6112d53f..0000000000 Binary files a/resources/sprite/status_1x/right-green.png and /dev/null differ diff --git a/resources/sprite/status_1x/right-red.png b/resources/sprite/status_1x/right-red.png deleted file mode 100644 index 7deab4df2d..0000000000 Binary files a/resources/sprite/status_1x/right-red.png and /dev/null differ diff --git a/resources/sprite/status_1x/right-white.png b/resources/sprite/status_1x/right-white.png deleted file mode 100644 index 78e1037014..0000000000 Binary files a/resources/sprite/status_1x/right-white.png and /dev/null differ diff --git a/resources/sprite/status_1x/right.png b/resources/sprite/status_1x/right.png deleted file mode 100644 index d1ad9f2a4f..0000000000 Binary files a/resources/sprite/status_1x/right.png and /dev/null differ diff --git a/resources/sprite/status_1x/time-green.png b/resources/sprite/status_1x/time-green.png deleted file mode 100644 index d514ed6853..0000000000 Binary files a/resources/sprite/status_1x/time-green.png and /dev/null differ diff --git a/resources/sprite/status_1x/time-orange.png b/resources/sprite/status_1x/time-orange.png deleted file mode 100644 index 1acad2715c..0000000000 Binary files a/resources/sprite/status_1x/time-orange.png and /dev/null differ diff --git a/resources/sprite/status_1x/time-red.png b/resources/sprite/status_1x/time-red.png deleted file mode 100644 index 5271c9a2af..0000000000 Binary files a/resources/sprite/status_1x/time-red.png and /dev/null differ diff --git a/resources/sprite/status_1x/time-yellow.png b/resources/sprite/status_1x/time-yellow.png deleted file mode 100644 index 0ed680ede4..0000000000 Binary files a/resources/sprite/status_1x/time-yellow.png and /dev/null differ diff --git a/resources/sprite/status_1x/up-blue.png b/resources/sprite/status_1x/up-blue.png deleted file mode 100644 index 5b9ad0bc76..0000000000 Binary files a/resources/sprite/status_1x/up-blue.png and /dev/null differ diff --git a/resources/sprite/status_1x/up-dark.png b/resources/sprite/status_1x/up-dark.png deleted file mode 100644 index 05e7fd15c5..0000000000 Binary files a/resources/sprite/status_1x/up-dark.png and /dev/null differ diff --git a/resources/sprite/status_1x/up-green.png b/resources/sprite/status_1x/up-green.png deleted file mode 100644 index c66ba2fd12..0000000000 Binary files a/resources/sprite/status_1x/up-green.png and /dev/null differ diff --git a/resources/sprite/status_1x/up-red.png b/resources/sprite/status_1x/up-red.png deleted file mode 100644 index ed73bffcd8..0000000000 Binary files a/resources/sprite/status_1x/up-red.png and /dev/null differ diff --git a/resources/sprite/status_1x/up-white.png b/resources/sprite/status_1x/up-white.png deleted file mode 100644 index d19bbf90f5..0000000000 Binary files a/resources/sprite/status_1x/up-white.png and /dev/null differ diff --git a/resources/sprite/status_1x/up.png b/resources/sprite/status_1x/up.png deleted file mode 100644 index 33d69869c4..0000000000 Binary files a/resources/sprite/status_1x/up.png and /dev/null differ diff --git a/resources/sprite/status_1x/warning-blue.png b/resources/sprite/status_1x/warning-blue.png deleted file mode 100644 index c3cc0625d3..0000000000 Binary files a/resources/sprite/status_1x/warning-blue.png and /dev/null differ diff --git a/resources/sprite/status_1x/warning-dark.png b/resources/sprite/status_1x/warning-dark.png deleted file mode 100644 index 33de2b39ff..0000000000 Binary files a/resources/sprite/status_1x/warning-dark.png and /dev/null differ diff --git a/resources/sprite/status_1x/warning-green.png b/resources/sprite/status_1x/warning-green.png deleted file mode 100644 index df2d007d07..0000000000 Binary files a/resources/sprite/status_1x/warning-green.png and /dev/null differ diff --git a/resources/sprite/status_1x/warning-red.png b/resources/sprite/status_1x/warning-red.png deleted file mode 100644 index eefd44cc42..0000000000 Binary files a/resources/sprite/status_1x/warning-red.png and /dev/null differ diff --git a/resources/sprite/status_1x/warning-white.png b/resources/sprite/status_1x/warning-white.png deleted file mode 100644 index ce515d61e4..0000000000 Binary files a/resources/sprite/status_1x/warning-white.png and /dev/null differ diff --git a/resources/sprite/status_1x/warning.png b/resources/sprite/status_1x/warning.png deleted file mode 100644 index 755960355d..0000000000 Binary files a/resources/sprite/status_1x/warning.png and /dev/null differ diff --git a/resources/sprite/status_2x/accept-blue.png b/resources/sprite/status_2x/accept-blue.png deleted file mode 100644 index 6b1586deb4..0000000000 Binary files a/resources/sprite/status_2x/accept-blue.png and /dev/null differ diff --git a/resources/sprite/status_2x/accept-dark.png b/resources/sprite/status_2x/accept-dark.png deleted file mode 100644 index 587d9af04d..0000000000 Binary files a/resources/sprite/status_2x/accept-dark.png and /dev/null differ diff --git a/resources/sprite/status_2x/accept-green.png b/resources/sprite/status_2x/accept-green.png deleted file mode 100644 index 9f681f26bc..0000000000 Binary files a/resources/sprite/status_2x/accept-green.png and /dev/null differ diff --git a/resources/sprite/status_2x/accept-red.png b/resources/sprite/status_2x/accept-red.png deleted file mode 100644 index 509273d5bb..0000000000 Binary files a/resources/sprite/status_2x/accept-red.png and /dev/null differ diff --git a/resources/sprite/status_2x/accept-white.png b/resources/sprite/status_2x/accept-white.png deleted file mode 100644 index 39efb34925..0000000000 Binary files a/resources/sprite/status_2x/accept-white.png and /dev/null differ diff --git a/resources/sprite/status_2x/accept.png b/resources/sprite/status_2x/accept.png deleted file mode 100644 index 3afd5e68da..0000000000 Binary files a/resources/sprite/status_2x/accept.png and /dev/null differ diff --git a/resources/sprite/status_2x/add-blue.png b/resources/sprite/status_2x/add-blue.png deleted file mode 100644 index 0edbb5db84..0000000000 Binary files a/resources/sprite/status_2x/add-blue.png and /dev/null differ diff --git a/resources/sprite/status_2x/add-dark.png b/resources/sprite/status_2x/add-dark.png deleted file mode 100644 index e3533fa0f7..0000000000 Binary files a/resources/sprite/status_2x/add-dark.png and /dev/null differ diff --git a/resources/sprite/status_2x/add-green.png b/resources/sprite/status_2x/add-green.png deleted file mode 100644 index 8eb93e897e..0000000000 Binary files a/resources/sprite/status_2x/add-green.png and /dev/null differ diff --git a/resources/sprite/status_2x/add-red.png b/resources/sprite/status_2x/add-red.png deleted file mode 100644 index e2ee8ba48d..0000000000 Binary files a/resources/sprite/status_2x/add-red.png and /dev/null differ diff --git a/resources/sprite/status_2x/add-white.png b/resources/sprite/status_2x/add-white.png deleted file mode 100644 index 71ad766187..0000000000 Binary files a/resources/sprite/status_2x/add-white.png and /dev/null differ diff --git a/resources/sprite/status_2x/add.png b/resources/sprite/status_2x/add.png deleted file mode 100644 index 75504bbb7d..0000000000 Binary files a/resources/sprite/status_2x/add.png and /dev/null differ diff --git a/resources/sprite/status_2x/down-blue.png b/resources/sprite/status_2x/down-blue.png deleted file mode 100644 index 185512d5cb..0000000000 Binary files a/resources/sprite/status_2x/down-blue.png and /dev/null differ diff --git a/resources/sprite/status_2x/down-dark.png b/resources/sprite/status_2x/down-dark.png deleted file mode 100644 index 5e6d2f48fd..0000000000 Binary files a/resources/sprite/status_2x/down-dark.png and /dev/null differ diff --git a/resources/sprite/status_2x/down-green.png b/resources/sprite/status_2x/down-green.png deleted file mode 100644 index 99a5ad61b3..0000000000 Binary files a/resources/sprite/status_2x/down-green.png and /dev/null differ diff --git a/resources/sprite/status_2x/down-red.png b/resources/sprite/status_2x/down-red.png deleted file mode 100644 index fc36c023dd..0000000000 Binary files a/resources/sprite/status_2x/down-red.png and /dev/null differ diff --git a/resources/sprite/status_2x/down-white.png b/resources/sprite/status_2x/down-white.png deleted file mode 100644 index 9a419a3a21..0000000000 Binary files a/resources/sprite/status_2x/down-white.png and /dev/null differ diff --git a/resources/sprite/status_2x/down.png b/resources/sprite/status_2x/down.png deleted file mode 100644 index b0b6bcfd55..0000000000 Binary files a/resources/sprite/status_2x/down.png and /dev/null differ diff --git a/resources/sprite/status_2x/info-blue.png b/resources/sprite/status_2x/info-blue.png deleted file mode 100644 index 92933a4eb7..0000000000 Binary files a/resources/sprite/status_2x/info-blue.png and /dev/null differ diff --git a/resources/sprite/status_2x/info-dark.png b/resources/sprite/status_2x/info-dark.png deleted file mode 100644 index ab82a1951a..0000000000 Binary files a/resources/sprite/status_2x/info-dark.png and /dev/null differ diff --git a/resources/sprite/status_2x/info-green.png b/resources/sprite/status_2x/info-green.png deleted file mode 100644 index 5913448a32..0000000000 Binary files a/resources/sprite/status_2x/info-green.png and /dev/null differ diff --git a/resources/sprite/status_2x/info-red.png b/resources/sprite/status_2x/info-red.png deleted file mode 100644 index 3571889bbe..0000000000 Binary files a/resources/sprite/status_2x/info-red.png and /dev/null differ diff --git a/resources/sprite/status_2x/info-white.png b/resources/sprite/status_2x/info-white.png deleted file mode 100644 index 8ef1aa7c09..0000000000 Binary files a/resources/sprite/status_2x/info-white.png and /dev/null differ diff --git a/resources/sprite/status_2x/info.png b/resources/sprite/status_2x/info.png deleted file mode 100644 index fc5f921a6a..0000000000 Binary files a/resources/sprite/status_2x/info.png and /dev/null differ diff --git a/resources/sprite/status_2x/left-blue.png b/resources/sprite/status_2x/left-blue.png deleted file mode 100644 index 297f594d89..0000000000 Binary files a/resources/sprite/status_2x/left-blue.png and /dev/null differ diff --git a/resources/sprite/status_2x/left-dark.png b/resources/sprite/status_2x/left-dark.png deleted file mode 100644 index 34aef33b96..0000000000 Binary files a/resources/sprite/status_2x/left-dark.png and /dev/null differ diff --git a/resources/sprite/status_2x/left-green.png b/resources/sprite/status_2x/left-green.png deleted file mode 100644 index 54c91f81b5..0000000000 Binary files a/resources/sprite/status_2x/left-green.png and /dev/null differ diff --git a/resources/sprite/status_2x/left-red.png b/resources/sprite/status_2x/left-red.png deleted file mode 100644 index ba9aa0e110..0000000000 Binary files a/resources/sprite/status_2x/left-red.png and /dev/null differ diff --git a/resources/sprite/status_2x/left-white.png b/resources/sprite/status_2x/left-white.png deleted file mode 100644 index a102b2f88d..0000000000 Binary files a/resources/sprite/status_2x/left-white.png and /dev/null differ diff --git a/resources/sprite/status_2x/left.png b/resources/sprite/status_2x/left.png deleted file mode 100644 index 871efb2c64..0000000000 Binary files a/resources/sprite/status_2x/left.png and /dev/null differ diff --git a/resources/sprite/status_2x/minus-blue.png b/resources/sprite/status_2x/minus-blue.png deleted file mode 100644 index 317ffed54f..0000000000 Binary files a/resources/sprite/status_2x/minus-blue.png and /dev/null differ diff --git a/resources/sprite/status_2x/minus-dark.png b/resources/sprite/status_2x/minus-dark.png deleted file mode 100644 index f72b136956..0000000000 Binary files a/resources/sprite/status_2x/minus-dark.png and /dev/null differ diff --git a/resources/sprite/status_2x/minus-green.png b/resources/sprite/status_2x/minus-green.png deleted file mode 100644 index ccb0efbb4a..0000000000 Binary files a/resources/sprite/status_2x/minus-green.png and /dev/null differ diff --git a/resources/sprite/status_2x/minus-red.png b/resources/sprite/status_2x/minus-red.png deleted file mode 100644 index f5e10318c6..0000000000 Binary files a/resources/sprite/status_2x/minus-red.png and /dev/null differ diff --git a/resources/sprite/status_2x/minus-white.png b/resources/sprite/status_2x/minus-white.png deleted file mode 100644 index ebcf13044e..0000000000 Binary files a/resources/sprite/status_2x/minus-white.png and /dev/null differ diff --git a/resources/sprite/status_2x/minus.png b/resources/sprite/status_2x/minus.png deleted file mode 100644 index 907cf18277..0000000000 Binary files a/resources/sprite/status_2x/minus.png and /dev/null differ diff --git a/resources/sprite/status_2x/oh-closed-dark.png b/resources/sprite/status_2x/oh-closed-dark.png deleted file mode 100644 index a88885ccff..0000000000 Binary files a/resources/sprite/status_2x/oh-closed-dark.png and /dev/null differ diff --git a/resources/sprite/status_2x/oh-closed.png b/resources/sprite/status_2x/oh-closed.png deleted file mode 100644 index 7c57c4d1e8..0000000000 Binary files a/resources/sprite/status_2x/oh-closed.png and /dev/null differ diff --git a/resources/sprite/status_2x/oh-ok-dark.png b/resources/sprite/status_2x/oh-ok-dark.png deleted file mode 100644 index f7437a7e53..0000000000 Binary files a/resources/sprite/status_2x/oh-ok-dark.png and /dev/null differ diff --git a/resources/sprite/status_2x/oh-ok.png b/resources/sprite/status_2x/oh-ok.png deleted file mode 100644 index 01d3a24747..0000000000 Binary files a/resources/sprite/status_2x/oh-ok.png and /dev/null differ diff --git a/resources/sprite/status_2x/oh-open-green.png b/resources/sprite/status_2x/oh-open-green.png deleted file mode 100644 index 2eb2b250a2..0000000000 Binary files a/resources/sprite/status_2x/oh-open-green.png and /dev/null differ diff --git a/resources/sprite/status_2x/oh-open-red.png b/resources/sprite/status_2x/oh-open-red.png deleted file mode 100644 index 198a3ff18a..0000000000 Binary files a/resources/sprite/status_2x/oh-open-red.png and /dev/null differ diff --git a/resources/sprite/status_2x/oh-open.png b/resources/sprite/status_2x/oh-open.png deleted file mode 100644 index 50786bcd21..0000000000 Binary files a/resources/sprite/status_2x/oh-open.png and /dev/null differ diff --git a/resources/sprite/status_2x/open-blue.png b/resources/sprite/status_2x/open-blue.png deleted file mode 100644 index 5a68c026f4..0000000000 Binary files a/resources/sprite/status_2x/open-blue.png and /dev/null differ diff --git a/resources/sprite/status_2x/open-dark.png b/resources/sprite/status_2x/open-dark.png deleted file mode 100644 index 2f06ccf4e9..0000000000 Binary files a/resources/sprite/status_2x/open-dark.png and /dev/null differ diff --git a/resources/sprite/status_2x/open-green.png b/resources/sprite/status_2x/open-green.png deleted file mode 100644 index 4e90c62d35..0000000000 Binary files a/resources/sprite/status_2x/open-green.png and /dev/null differ diff --git a/resources/sprite/status_2x/open-red.png b/resources/sprite/status_2x/open-red.png deleted file mode 100644 index 8c7fe4b8a0..0000000000 Binary files a/resources/sprite/status_2x/open-red.png and /dev/null differ diff --git a/resources/sprite/status_2x/open-white.png b/resources/sprite/status_2x/open-white.png deleted file mode 100644 index de5b7d226c..0000000000 Binary files a/resources/sprite/status_2x/open-white.png and /dev/null differ diff --git a/resources/sprite/status_2x/open.png b/resources/sprite/status_2x/open.png deleted file mode 100644 index cc2cd21d7f..0000000000 Binary files a/resources/sprite/status_2x/open.png and /dev/null differ diff --git a/resources/sprite/status_2x/pl-summary.png b/resources/sprite/status_2x/pl-summary.png deleted file mode 100644 index 0a8e863c88..0000000000 Binary files a/resources/sprite/status_2x/pl-summary.png and /dev/null differ diff --git a/resources/sprite/status_2x/pl-testplan.png b/resources/sprite/status_2x/pl-testplan.png deleted file mode 100644 index 3f9613fe5b..0000000000 Binary files a/resources/sprite/status_2x/pl-testplan.png and /dev/null differ diff --git a/resources/sprite/status_2x/policy-admin-white.png b/resources/sprite/status_2x/policy-admin-white.png deleted file mode 100644 index c09d9c305f..0000000000 Binary files a/resources/sprite/status_2x/policy-admin-white.png and /dev/null differ diff --git a/resources/sprite/status_2x/policy-admin.png b/resources/sprite/status_2x/policy-admin.png deleted file mode 100644 index 8421b277dc..0000000000 Binary files a/resources/sprite/status_2x/policy-admin.png and /dev/null differ diff --git a/resources/sprite/status_2x/policy-all-white.png b/resources/sprite/status_2x/policy-all-white.png deleted file mode 100644 index fe00c57c2a..0000000000 Binary files a/resources/sprite/status_2x/policy-all-white.png and /dev/null differ diff --git a/resources/sprite/status_2x/policy-all.png b/resources/sprite/status_2x/policy-all.png deleted file mode 100644 index 42053e8528..0000000000 Binary files a/resources/sprite/status_2x/policy-all.png and /dev/null differ diff --git a/resources/sprite/status_2x/policy-custom-white.png b/resources/sprite/status_2x/policy-custom-white.png deleted file mode 100644 index 450137cb61..0000000000 Binary files a/resources/sprite/status_2x/policy-custom-white.png and /dev/null differ diff --git a/resources/sprite/status_2x/policy-custom.png b/resources/sprite/status_2x/policy-custom.png deleted file mode 100644 index 64a67fe0a8..0000000000 Binary files a/resources/sprite/status_2x/policy-custom.png and /dev/null differ diff --git a/resources/sprite/status_2x/policy-elist-white.png b/resources/sprite/status_2x/policy-elist-white.png deleted file mode 100644 index 852310a56c..0000000000 Binary files a/resources/sprite/status_2x/policy-elist-white.png and /dev/null differ diff --git a/resources/sprite/status_2x/policy-elist.png b/resources/sprite/status_2x/policy-elist.png deleted file mode 100644 index a1ce7c050f..0000000000 Binary files a/resources/sprite/status_2x/policy-elist.png and /dev/null differ diff --git a/resources/sprite/status_2x/policy-noone-white.png b/resources/sprite/status_2x/policy-noone-white.png deleted file mode 100644 index 219a67bbd3..0000000000 Binary files a/resources/sprite/status_2x/policy-noone-white.png and /dev/null differ diff --git a/resources/sprite/status_2x/policy-noone.png b/resources/sprite/status_2x/policy-noone.png deleted file mode 100644 index 4b11d3f01f..0000000000 Binary files a/resources/sprite/status_2x/policy-noone.png and /dev/null differ diff --git a/resources/sprite/status_2x/policy-project-white.png b/resources/sprite/status_2x/policy-project-white.png deleted file mode 100644 index 8289755fdb..0000000000 Binary files a/resources/sprite/status_2x/policy-project-white.png and /dev/null differ diff --git a/resources/sprite/status_2x/policy-project.png b/resources/sprite/status_2x/policy-project.png deleted file mode 100644 index 4d777ca0b0..0000000000 Binary files a/resources/sprite/status_2x/policy-project.png and /dev/null differ diff --git a/resources/sprite/status_2x/policy-public-white.png b/resources/sprite/status_2x/policy-public-white.png deleted file mode 100644 index 719c0fd44f..0000000000 Binary files a/resources/sprite/status_2x/policy-public-white.png and /dev/null differ diff --git a/resources/sprite/status_2x/policy-public.png b/resources/sprite/status_2x/policy-public.png deleted file mode 100644 index 339c8dbc2a..0000000000 Binary files a/resources/sprite/status_2x/policy-public.png and /dev/null differ diff --git a/resources/sprite/status_2x/policy-unknown-white.png b/resources/sprite/status_2x/policy-unknown-white.png deleted file mode 100644 index a3f73a38d1..0000000000 Binary files a/resources/sprite/status_2x/policy-unknown-white.png and /dev/null differ diff --git a/resources/sprite/status_2x/policy-unknown.png b/resources/sprite/status_2x/policy-unknown.png deleted file mode 100644 index d6df5f1a1a..0000000000 Binary files a/resources/sprite/status_2x/policy-unknown.png and /dev/null differ diff --git a/resources/sprite/status_2x/policy-user-white.png b/resources/sprite/status_2x/policy-user-white.png deleted file mode 100644 index 913c892356..0000000000 Binary files a/resources/sprite/status_2x/policy-user-white.png and /dev/null differ diff --git a/resources/sprite/status_2x/policy-user.png b/resources/sprite/status_2x/policy-user.png deleted file mode 100644 index 3d6fcf050b..0000000000 Binary files a/resources/sprite/status_2x/policy-user.png and /dev/null differ diff --git a/resources/sprite/status_2x/question-blue.png b/resources/sprite/status_2x/question-blue.png deleted file mode 100644 index d9fdd76b7a..0000000000 Binary files a/resources/sprite/status_2x/question-blue.png and /dev/null differ diff --git a/resources/sprite/status_2x/question-dark.png b/resources/sprite/status_2x/question-dark.png deleted file mode 100644 index c53f443d91..0000000000 Binary files a/resources/sprite/status_2x/question-dark.png and /dev/null differ diff --git a/resources/sprite/status_2x/question-green.png b/resources/sprite/status_2x/question-green.png deleted file mode 100644 index 5107b89154..0000000000 Binary files a/resources/sprite/status_2x/question-green.png and /dev/null differ diff --git a/resources/sprite/status_2x/question-red.png b/resources/sprite/status_2x/question-red.png deleted file mode 100644 index 068a369390..0000000000 Binary files a/resources/sprite/status_2x/question-red.png and /dev/null differ diff --git a/resources/sprite/status_2x/question-white.png b/resources/sprite/status_2x/question-white.png deleted file mode 100644 index c1caf7419f..0000000000 Binary files a/resources/sprite/status_2x/question-white.png and /dev/null differ diff --git a/resources/sprite/status_2x/question.png b/resources/sprite/status_2x/question.png deleted file mode 100644 index 7e187f357d..0000000000 Binary files a/resources/sprite/status_2x/question.png and /dev/null differ diff --git a/resources/sprite/status_2x/reject-blue.png b/resources/sprite/status_2x/reject-blue.png deleted file mode 100644 index 8789cd9be2..0000000000 Binary files a/resources/sprite/status_2x/reject-blue.png and /dev/null differ diff --git a/resources/sprite/status_2x/reject-dark.png b/resources/sprite/status_2x/reject-dark.png deleted file mode 100644 index c1991c6eb9..0000000000 Binary files a/resources/sprite/status_2x/reject-dark.png and /dev/null differ diff --git a/resources/sprite/status_2x/reject-green.png b/resources/sprite/status_2x/reject-green.png deleted file mode 100644 index 7f49eebad0..0000000000 Binary files a/resources/sprite/status_2x/reject-green.png and /dev/null differ diff --git a/resources/sprite/status_2x/reject-red.png b/resources/sprite/status_2x/reject-red.png deleted file mode 100644 index e0f29d1bf3..0000000000 Binary files a/resources/sprite/status_2x/reject-red.png and /dev/null differ diff --git a/resources/sprite/status_2x/reject-white.png b/resources/sprite/status_2x/reject-white.png deleted file mode 100644 index ff7a314ae5..0000000000 Binary files a/resources/sprite/status_2x/reject-white.png and /dev/null differ diff --git a/resources/sprite/status_2x/reject.png b/resources/sprite/status_2x/reject.png deleted file mode 100644 index 06a90b023d..0000000000 Binary files a/resources/sprite/status_2x/reject.png and /dev/null differ diff --git a/resources/sprite/status_2x/right-blue.png b/resources/sprite/status_2x/right-blue.png deleted file mode 100644 index 81be3ae7e9..0000000000 Binary files a/resources/sprite/status_2x/right-blue.png and /dev/null differ diff --git a/resources/sprite/status_2x/right-dark.png b/resources/sprite/status_2x/right-dark.png deleted file mode 100644 index ae92e97193..0000000000 Binary files a/resources/sprite/status_2x/right-dark.png and /dev/null differ diff --git a/resources/sprite/status_2x/right-green.png b/resources/sprite/status_2x/right-green.png deleted file mode 100644 index d7290b18d5..0000000000 Binary files a/resources/sprite/status_2x/right-green.png and /dev/null differ diff --git a/resources/sprite/status_2x/right-red.png b/resources/sprite/status_2x/right-red.png deleted file mode 100644 index 3f1d48e223..0000000000 Binary files a/resources/sprite/status_2x/right-red.png and /dev/null differ diff --git a/resources/sprite/status_2x/right-white.png b/resources/sprite/status_2x/right-white.png deleted file mode 100644 index 0261cc0784..0000000000 Binary files a/resources/sprite/status_2x/right-white.png and /dev/null differ diff --git a/resources/sprite/status_2x/right.png b/resources/sprite/status_2x/right.png deleted file mode 100644 index 06190d0d1b..0000000000 Binary files a/resources/sprite/status_2x/right.png and /dev/null differ diff --git a/resources/sprite/status_2x/time-green.png b/resources/sprite/status_2x/time-green.png deleted file mode 100644 index 65ea095bd3..0000000000 Binary files a/resources/sprite/status_2x/time-green.png and /dev/null differ diff --git a/resources/sprite/status_2x/time-orange.png b/resources/sprite/status_2x/time-orange.png deleted file mode 100644 index 14ddd5f45f..0000000000 Binary files a/resources/sprite/status_2x/time-orange.png and /dev/null differ diff --git a/resources/sprite/status_2x/time-red.png b/resources/sprite/status_2x/time-red.png deleted file mode 100644 index 118dc561f2..0000000000 Binary files a/resources/sprite/status_2x/time-red.png and /dev/null differ diff --git a/resources/sprite/status_2x/time-yellow.png b/resources/sprite/status_2x/time-yellow.png deleted file mode 100644 index 7735d549bd..0000000000 Binary files a/resources/sprite/status_2x/time-yellow.png and /dev/null differ diff --git a/resources/sprite/status_2x/up-blue.png b/resources/sprite/status_2x/up-blue.png deleted file mode 100644 index ed96bd604a..0000000000 Binary files a/resources/sprite/status_2x/up-blue.png and /dev/null differ diff --git a/resources/sprite/status_2x/up-dark.png b/resources/sprite/status_2x/up-dark.png deleted file mode 100644 index 1f43a5a127..0000000000 Binary files a/resources/sprite/status_2x/up-dark.png and /dev/null differ diff --git a/resources/sprite/status_2x/up-green.png b/resources/sprite/status_2x/up-green.png deleted file mode 100644 index 4406e3496b..0000000000 Binary files a/resources/sprite/status_2x/up-green.png and /dev/null differ diff --git a/resources/sprite/status_2x/up-red.png b/resources/sprite/status_2x/up-red.png deleted file mode 100644 index 262c6730ec..0000000000 Binary files a/resources/sprite/status_2x/up-red.png and /dev/null differ diff --git a/resources/sprite/status_2x/up-white.png b/resources/sprite/status_2x/up-white.png deleted file mode 100644 index f59b378c14..0000000000 Binary files a/resources/sprite/status_2x/up-white.png and /dev/null differ diff --git a/resources/sprite/status_2x/up.png b/resources/sprite/status_2x/up.png deleted file mode 100644 index 24dea011c9..0000000000 Binary files a/resources/sprite/status_2x/up.png and /dev/null differ diff --git a/resources/sprite/status_2x/warning-blue.png b/resources/sprite/status_2x/warning-blue.png deleted file mode 100644 index 5a88becb1e..0000000000 Binary files a/resources/sprite/status_2x/warning-blue.png and /dev/null differ diff --git a/resources/sprite/status_2x/warning-dark.png b/resources/sprite/status_2x/warning-dark.png deleted file mode 100644 index 4b1eb3dee8..0000000000 Binary files a/resources/sprite/status_2x/warning-dark.png and /dev/null differ diff --git a/resources/sprite/status_2x/warning-green.png b/resources/sprite/status_2x/warning-green.png deleted file mode 100644 index 3ec7ec00f6..0000000000 Binary files a/resources/sprite/status_2x/warning-green.png and /dev/null differ diff --git a/resources/sprite/status_2x/warning-red.png b/resources/sprite/status_2x/warning-red.png deleted file mode 100644 index ad3c2d036c..0000000000 Binary files a/resources/sprite/status_2x/warning-red.png and /dev/null differ diff --git a/resources/sprite/status_2x/warning-white.png b/resources/sprite/status_2x/warning-white.png deleted file mode 100644 index 52814bc4af..0000000000 Binary files a/resources/sprite/status_2x/warning-white.png and /dev/null differ diff --git a/resources/sprite/status_2x/warning.png b/resources/sprite/status_2x/warning.png deleted file mode 100644 index baa2144ba6..0000000000 Binary files a/resources/sprite/status_2x/warning.png and /dev/null differ diff --git a/scripts/celerity/generate_sprites.php b/scripts/celerity/generate_sprites.php index 55574cfa54..4d75c97bda 100755 --- a/scripts/celerity/generate_sprites.php +++ b/scripts/celerity/generate_sprites.php @@ -1,94 +1,93 @@ #!/usr/bin/env php <?php require_once dirname(dirname(__FILE__)).'/__init_script__.php'; $args = new PhutilArgumentParser($argv); $args->setTagline('regenerate CSS sprite sheets'); $args->setSynopsis(<<<EOHELP **sprites** Rebuild CSS sprite sheets. EOHELP ); $args->parseStandardArguments(); $args->parse( array( array( 'name' => 'force', 'help' => 'Force regeneration even if sources have not changed.', ), )); $root = dirname(phutil_get_library_root('phabricator')); $webroot = $root.'/webroot/rsrc'; $webroot = Filesystem::readablePath($webroot); $generator = new CeleritySpriteGenerator(); $sheets = array( 'remarkup' => $generator->buildRemarkupSheet(), 'menu' => $generator->buildMenuSheet(), 'apps' => $generator->buildAppsSheet(), 'actions' => $generator->buildActionsSheet(), 'minicons' => $generator->buildMiniconsSheet(), 'conpherence' => $generator->buildConpherenceSheet(), 'apps-large' => $generator->buildAppsLargeSheet(), 'payments' => $generator->buildPaymentsSheet(), 'tokens' => $generator->buildTokenSheet(), 'buttonbar' => $generator->buildButtonBarSheet(), 'docs' => $generator->buildDocsSheet(), 'gradient' => $generator->buildGradientSheet(), 'main-header' => $generator->buildMainHeaderSheet(), 'login' => $generator->buildLoginSheet(), - 'status' => $generator->buildStatusSheet(), 'projects' => $generator->buildProjectsSheet(), ); list($err) = exec_manual('optipng'); if ($err) { $have_optipng = false; echo phutil_console_format( "<bg:red> WARNING </bg> `optipng` not found in PATH.\n". "Sprites will not be optimized! Install `optipng`!\n"); } else { $have_optipng = true; } foreach ($sheets as $name => $sheet) { $sheet->setBasePath($root); $manifest_path = $root.'/resources/sprite/manifest/'.$name.'.json'; if (!$args->getArg('force')) { if (Filesystem::pathExists($manifest_path)) { $data = Filesystem::readFile($manifest_path); $data = json_decode($data, true); if (!$sheet->needsRegeneration($data)) { continue; } } } $sheet ->generateCSS($webroot."/css/sprite-{$name}.css") ->generateManifest($root."/resources/sprite/manifest/{$name}.json"); foreach ($sheet->getScales() as $scale) { if ($scale == 1) { $sheet_name = "sprite-{$name}.png"; } else { $sheet_name = "sprite-{$name}-X{$scale}.png"; } $full_path = "{$webroot}/image/{$sheet_name}"; $sheet->generateImage($full_path, $scale); if ($have_optipng) { echo "Optimizing...\n"; phutil_passthru('optipng -o7 -clobber %s', $full_path); } } } echo "Done.\n"; diff --git a/src/applications/conpherence/view/ConpherenceLayoutView.php b/src/applications/conpherence/view/ConpherenceLayoutView.php index 877559f3a1..3bd75347d8 100644 --- a/src/applications/conpherence/view/ConpherenceLayoutView.php +++ b/src/applications/conpherence/view/ConpherenceLayoutView.php @@ -1,239 +1,239 @@ <?php final class ConpherenceLayoutView extends AphrontView { private $thread; private $baseURI; private $threadView; private $role; private $header; private $messages; private $replyForm; public function setMessages($messages) { $this->messages = $messages; return $this; } public function setReplyForm($reply_form) { $this->replyForm = $reply_form; return $this; } public function setHeader($header) { $this->header = $header; return $this; } public function setRole($role) { $this->role = $role; return $this; } public function getThreadView() { return $this->threadView; } public function setBaseURI($base_uri) { $this->baseURI = $base_uri; return $this; } public function setThread(ConpherenceThread $thread) { $this->thread = $thread; return $this; } public function setThreadView(ConpherenceThreadListView $thead_view) { $this->threadView = $thead_view; return $this; } public function render() { require_celerity_resource('conpherence-menu-css'); require_celerity_resource('conpherence-message-pane-css'); require_celerity_resource('conpherence-widget-pane-css'); $layout_id = celerity_generate_unique_node_id(); $selected_id = null; $selected_thread_id = null; if ($this->thread) { $selected_id = $this->thread->getPHID() . '-nav-item'; $selected_thread_id = $this->thread->getID(); } $this->initBehavior('conpherence-menu', array( 'baseURI' => $this->baseURI, 'layoutID' => $layout_id, 'selectedID' => $selected_id, 'selectedThreadID' => $selected_thread_id, 'role' => $this->role, 'hasThreadList' => (bool)$this->threadView, 'hasThread' => (bool)$this->messages, 'hasWidgets' => false, )); $this->initBehavior( 'conpherence-widget-pane', array( 'widgetBaseUpdateURI' => $this->baseURI . 'update/', 'widgetRegistry' => array( 'conpherence-message-pane' => array( 'name' => pht('Thread'), - 'icon' => 'comment', + 'icon' => 'fa-comment', 'deviceOnly' => true, 'hasCreate' => false ), 'widgets-people' => array( 'name' => pht('Participants'), - 'icon' => 'user', + 'icon' => 'fa-users', 'deviceOnly' => false, 'hasCreate' => true, 'createData' => array( 'refreshFromResponse' => true, 'action' => ConpherenceUpdateActions::ADD_PERSON, 'customHref' => null ) ), 'widgets-files' => array( 'name' => pht('Files'), - 'icon' => 'file', + 'icon' => 'fa-files-o', 'deviceOnly' => false, 'hasCreate' => false ), 'widgets-calendar' => array( 'name' => pht('Calendar'), - 'icon' => 'calendar', + 'icon' => 'fa-calendar', 'deviceOnly' => false, 'hasCreate' => true, 'createData' => array( 'refreshFromResponse' => false, 'action' => ConpherenceUpdateActions::ADD_STATUS, 'customHref' => '/calendar/event/create/' ) ), 'widgets-settings' => array( 'name' => pht('Settings'), - 'icon' => 'wrench', + 'icon' => 'fa-wrench', 'deviceOnly' => false, 'hasCreate' => false ), ))); return javelin_tag( 'div', array( 'id' => $layout_id, 'sigil' => 'conpherence-layout', 'class' => 'conpherence-layout conpherence-role-'.$this->role, ), array( javelin_tag( 'div', array( 'class' => 'phabricator-nav-column-background', 'sigil' => 'phabricator-nav-column-background', ), ''), javelin_tag( 'div', array( 'id' => 'conpherence-menu-pane', 'class' => 'conpherence-menu-pane phabricator-side-menu', 'sigil' => 'conpherence-menu-pane', ), $this->threadView), javelin_tag( 'div', array( 'class' => 'conpherence-content-pane', ), array( javelin_tag( 'div', array( 'class' => 'conpherence-header-pane', 'id' => 'conpherence-header-pane', 'sigil' => 'conpherence-header-pane', ), nonempty($this->header, '')), javelin_tag( 'div', array( 'class' => 'conpherence-no-threads', 'sigil' => 'conpherence-no-threads', 'style' => 'display: none;', ), array( phutil_tag( 'div', array( 'class' => 'text' ), pht('You do not have any messages yet.')), javelin_tag( 'a', array( 'href' => '/conpherence/new/', 'class' => 'button grey', 'sigil' => 'workflow', ), pht('Send a Message')) )), javelin_tag( 'div', array( 'class' => 'conpherence-widget-pane', 'id' => 'conpherence-widget-pane', 'sigil' => 'conpherence-widget-pane', ), array( phutil_tag( 'div', array( 'class' => 'widgets-loading-mask' ), ''), javelin_tag( 'div', array( 'sigil' => 'conpherence-widgets-holder' ), ''))), javelin_tag( 'div', array( 'class' => 'conpherence-message-pane', 'id' => 'conpherence-message-pane', 'sigil' => 'conpherence-message-pane' ), array( javelin_tag( 'div', array( 'class' => 'conpherence-messages', 'id' => 'conpherence-messages', 'sigil' => 'conpherence-messages', ), nonempty($this->messages, '')), phutil_tag( 'div', array( 'class' => 'messages-loading-mask', ), ''), javelin_tag( 'div', array( 'id' => 'conpherence-form', 'sigil' => 'conpherence-form' ), nonempty($this->replyForm, '')) )), )), )); } } diff --git a/src/applications/differential/constants/DifferentialRevisionStatus.php b/src/applications/differential/constants/DifferentialRevisionStatus.php index 64a330dc7e..61340d0111 100644 --- a/src/applications/differential/constants/DifferentialRevisionStatus.php +++ b/src/applications/differential/constants/DifferentialRevisionStatus.php @@ -1,115 +1,114 @@ <?php /** * NOTE: you probably want {@class:ArcanistDifferentialRevisionStatus}. * This class just contains a mapping for color within the Differential * application. */ final class DifferentialRevisionStatus { const COLOR_STATUS_DEFAULT = 'status'; const COLOR_STATUS_DARK = 'status-dark'; const COLOR_STATUS_GREEN = 'status-green'; const COLOR_STATUS_RED = 'status-red'; public static function getRevisionStatusColor($status) { $default = self::COLOR_STATUS_DEFAULT; $map = array( ArcanistDifferentialRevisionStatus::NEEDS_REVIEW => self::COLOR_STATUS_DEFAULT, ArcanistDifferentialRevisionStatus::NEEDS_REVISION => self::COLOR_STATUS_RED, ArcanistDifferentialRevisionStatus::CHANGES_PLANNED => self::COLOR_STATUS_RED, ArcanistDifferentialRevisionStatus::ACCEPTED => self::COLOR_STATUS_GREEN, ArcanistDifferentialRevisionStatus::CLOSED => self::COLOR_STATUS_DARK, ArcanistDifferentialRevisionStatus::ABANDONED => self::COLOR_STATUS_DARK, ArcanistDifferentialRevisionStatus::IN_PREPARATION => self::COLOR_STATUS_DARK, ); return idx($map, $status, $default); } public static function getRevisionStatusIcon($status) { - $default = 'oh-open'; + $default = 'fa-square-o bluegrey'; $map = array( ArcanistDifferentialRevisionStatus::NEEDS_REVIEW => - 'oh-open', + 'fa-square-o bluegrey', ArcanistDifferentialRevisionStatus::NEEDS_REVISION => - 'oh-open-red', + 'fa-square-o red', ArcanistDifferentialRevisionStatus::CHANGES_PLANNED => - 'oh-open-red', + 'fa-square-o red', ArcanistDifferentialRevisionStatus::ACCEPTED => - 'oh-open-green', + 'fa-square-o green', ArcanistDifferentialRevisionStatus::CLOSED => - 'oh-closed-dark', + 'fa-check-square-o', ArcanistDifferentialRevisionStatus::ABANDONED => - 'oh-closed-dark', + 'fa-check-square-o', ArcanistDifferentialRevisionStatus::IN_PREPARATION => - 'question-blue', + 'fa-question-circle blue', ); return idx($map, $status, $default); } public static function renderFullDescription($status) { $color = self::getRevisionStatusColor($status); $status_name = ArcanistDifferentialRevisionStatus::getNameForRevisionStatus($status); $img = id(new PHUIIconView()) - ->setSpriteSheet(PHUIIconView::SPRITE_STATUS) - ->setSpriteIcon(self::getRevisionStatusIcon($status)); + ->setIconFont(self::getRevisionStatusIcon($status)); $tag = phutil_tag( 'span', array( 'class' => 'phui-header-'.$color.' plr', ), array( $img, $status_name, )); return $tag; } public static function getClosedStatuses() { $statuses = array( ArcanistDifferentialRevisionStatus::CLOSED, ArcanistDifferentialRevisionStatus::ABANDONED, ); if (PhabricatorEnv::getEnvConfig('differential.close-on-accept')) { $statuses[] = ArcanistDifferentialRevisionStatus::ACCEPTED; } return $statuses; } public static function getOpenStatuses() { return array_diff(self::getAllStatuses(), self::getClosedStatuses()); } public static function getAllStatuses() { return array( ArcanistDifferentialRevisionStatus::NEEDS_REVIEW, ArcanistDifferentialRevisionStatus::NEEDS_REVISION, ArcanistDifferentialRevisionStatus::CHANGES_PLANNED, ArcanistDifferentialRevisionStatus::ACCEPTED, ArcanistDifferentialRevisionStatus::CLOSED, ArcanistDifferentialRevisionStatus::ABANDONED, ArcanistDifferentialRevisionStatus::IN_PREPARATION, ); } public static function isClosedStatus($status) { return in_array($status, self::getClosedStatuses()); } } diff --git a/src/applications/diffusion/controller/DiffusionRepositoryController.php b/src/applications/diffusion/controller/DiffusionRepositoryController.php index 2149b8ef49..f58e9d3c8e 100644 --- a/src/applications/diffusion/controller/DiffusionRepositoryController.php +++ b/src/applications/diffusion/controller/DiffusionRepositoryController.php @@ -1,640 +1,640 @@ <?php final class DiffusionRepositoryController extends DiffusionController { public function shouldAllowPublic() { return true; } public function processRequest() { $drequest = $this->getDiffusionRequest(); $repository = $drequest->getRepository(); $content = array(); $crumbs = $this->buildCrumbs(); $content[] = $crumbs; $content[] = $this->buildPropertiesTable($drequest->getRepository()); $phids = array(); try { $history_results = $this->callConduitWithDiffusionRequest( 'diffusion.historyquery', array( 'commit' => $drequest->getCommit(), 'path' => $drequest->getPath(), 'offset' => 0, 'limit' => 15)); $history = DiffusionPathChange::newFromConduit( $history_results['pathChanges']); foreach ($history as $item) { $data = $item->getCommitData(); if ($data) { if ($data->getCommitDetail('authorPHID')) { $phids[$data->getCommitDetail('authorPHID')] = true; } if ($data->getCommitDetail('committerPHID')) { $phids[$data->getCommitDetail('committerPHID')] = true; } } } $history_exception = null; } catch (Exception $ex) { $history_results = null; $history = null; $history_exception = $ex; } try { $browse_results = DiffusionBrowseResultSet::newFromConduit( $this->callConduitWithDiffusionRequest( 'diffusion.browsequery', array( 'path' => $drequest->getPath(), 'commit' => $drequest->getCommit(), ))); $browse_paths = $browse_results->getPaths(); foreach ($browse_paths as $item) { $data = $item->getLastCommitData(); if ($data) { if ($data->getCommitDetail('authorPHID')) { $phids[$data->getCommitDetail('authorPHID')] = true; } if ($data->getCommitDetail('committerPHID')) { $phids[$data->getCommitDetail('committerPHID')] = true; } } } $browse_exception = null; } catch (Exception $ex) { $browse_results = null; $browse_paths = null; $browse_exception = $ex; } $phids = array_keys($phids); $handles = $this->loadViewerHandles($phids); if ($browse_results) { $readme = $this->callConduitWithDiffusionRequest( 'diffusion.readmequery', array( 'paths' => $browse_results->getPathDicts(), 'commit' => $drequest->getStableCommit(), )); } else { $readme = null; } $content[] = $this->buildBrowseTable( $browse_results, $browse_paths, $browse_exception, $handles); $content[] = $this->buildHistoryTable( $history_results, $history, $history_exception, $handles); try { $content[] = $this->buildTagListTable($drequest); } catch (Exception $ex) { if (!$repository->isImporting()) { $content[] = $this->renderStatusMessage( pht('Unable to Load Tags'), $ex->getMessage()); } } try { $content[] = $this->buildBranchListTable($drequest); } catch (Exception $ex) { if (!$repository->isImporting()) { $content[] = $this->renderStatusMessage( pht('Unable to Load Branches'), $ex->getMessage()); } } if ($readme) { $box = new PHUIBoxView(); $box->appendChild($readme); $box->addPadding(PHUI::PADDING_LARGE); $panel = new PHUIObjectBoxView(); $panel->setHeaderText(pht('README')); $panel->appendChild($box); $content[] = $panel; } return $this->buildApplicationPage( $content, array( 'title' => $drequest->getRepository()->getName(), 'device' => true, )); } private function buildPropertiesTable(PhabricatorRepository $repository) { $user = $this->getRequest()->getUser(); $header = id(new PHUIHeaderView()) ->setHeader($repository->getName()) ->setUser($user) ->setPolicyObject($repository); if (!$repository->isTracked()) { - $header->setStatus('policy-noone', '', pht('Inactive')); + $header->setStatus('fa-ban', 'dark', pht('Inactive')); } else if ($repository->isImporting()) { - $header->setStatus('time', 'red', pht('Importing...')); + $header->setStatus('fa-clock-o', 'indigo', pht('Importing...')); } else { - $header->setStatus('oh-ok', '', pht('Active')); + $header->setStatus('fa-check', 'bluegrey', pht('Active')); } $actions = $this->buildActionList($repository); $view = id(new PHUIPropertyListView()) ->setUser($user); $project_phids = PhabricatorEdgeQuery::loadDestinationPHIDs( $repository->getPHID(), PhabricatorEdgeConfig::TYPE_OBJECT_HAS_PROJECT); if ($project_phids) { $this->loadHandles($project_phids); $view->addProperty( pht('Projects'), $this->renderHandlesForPHIDs($project_phids)); } if ($repository->isHosted()) { $ssh_uri = $repository->getSSHCloneURIObject(); if ($ssh_uri) { $clone_uri = $this->renderCloneCommand( $repository, $ssh_uri, $repository->getServeOverSSH(), '/settings/panel/ssh/'); $view->addProperty( $repository->isSVN() ? pht('Checkout (SSH)') : pht('Clone (SSH)'), $clone_uri); } $http_uri = $repository->getHTTPCloneURIObject(); if ($http_uri) { $clone_uri = $this->renderCloneCommand( $repository, $http_uri, $repository->getServeOverHTTP(), PhabricatorEnv::getEnvConfig('diffusion.allow-http-auth') ? '/settings/panel/vcspassword/' : null); $view->addProperty( $repository->isSVN() ? pht('Checkout (HTTP)') : pht('Clone (HTTP)'), $clone_uri); } } else { switch ($repository->getVersionControlSystem()) { case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: $view->addProperty( pht('Clone'), $this->renderCloneCommand( $repository, $repository->getPublicCloneURI())); break; case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: $view->addProperty( pht('Checkout'), $this->renderCloneCommand( $repository, $repository->getPublicCloneURI())); break; } } $description = $repository->getDetail('description'); if (strlen($description)) { $description = PhabricatorMarkupEngine::renderOneObject( $repository, 'description', $user); $view->addSectionHeader(pht('Description')); $view->addTextContent($description); } $view->setActionList($actions); return id(new PHUIObjectBoxView()) ->setHeader($header) ->addPropertyList($view); } private function buildBranchListTable(DiffusionRequest $drequest) { $viewer = $this->getRequest()->getUser(); if ($drequest->getBranch() === null) { return null; } $limit = 15; $branches = $this->callConduitWithDiffusionRequest( 'diffusion.branchquery', array( 'limit' => $limit + 1, )); if (!$branches) { return null; } $more_branches = (count($branches) > $limit); $branches = array_slice($branches, 0, $limit); $branches = DiffusionRepositoryRef::loadAllFromDictionaries($branches); $commits = id(new DiffusionCommitQuery()) ->setViewer($viewer) ->withIdentifiers(mpull($branches, 'getCommitIdentifier')) ->withRepository($drequest->getRepository()) ->execute(); $table = id(new DiffusionBranchTableView()) ->setUser($viewer) ->setDiffusionRequest($drequest) ->setBranches($branches) ->setCommits($commits); $panel = new PHUIObjectBoxView(); $header = new PHUIHeaderView(); $header->setHeader(pht('Branches')); if ($more_branches) { $header->setSubHeader(pht('Showing %d branches.', $limit)); } $icon = id(new PHUIIconView()) ->setIconFont('fa-fork'); $button = new PHUIButtonView(); $button->setText(pht("Show All Branches")); $button->setTag('a'); $button->setIcon($icon); $button->setHref($drequest->generateURI( array( 'action' => 'branches', ))); $header->addActionLink($button); $panel->setHeader($header); $panel->appendChild($table); return $panel; } private function buildTagListTable(DiffusionRequest $drequest) { $viewer = $this->getRequest()->getUser(); $tag_limit = 15; $tags = array(); try { $tags = DiffusionRepositoryTag::newFromConduit( $this->callConduitWithDiffusionRequest( 'diffusion.tagsquery', array( // On the home page, we want to find tags on any branch. 'commit' => null, 'limit' => $tag_limit + 1, ))); } catch (ConduitException $e) { if ($e->getMessage() != 'ERR-UNSUPPORTED-VCS') { throw $e; } } if (!$tags) { return null; } $more_tags = (count($tags) > $tag_limit); $tags = array_slice($tags, 0, $tag_limit); $commits = id(new DiffusionCommitQuery()) ->setViewer($viewer) ->withIdentifiers(mpull($tags, 'getCommitIdentifier')) ->withRepository($drequest->getRepository()) ->needCommitData(true) ->execute(); $view = id(new DiffusionTagListView()) ->setUser($viewer) ->setDiffusionRequest($drequest) ->setTags($tags) ->setCommits($commits); $phids = $view->getRequiredHandlePHIDs(); $handles = $this->loadViewerHandles($phids); $view->setHandles($handles); $panel = new PHUIObjectBoxView(); $header = new PHUIHeaderView(); $header->setHeader(pht('Tags')); if ($more_tags) { $header->setSubHeader( pht('Showing the %d most recent tags.', $tag_limit)); } $icon = id(new PHUIIconView()) ->setIconFont('fa-tag'); $button = new PHUIButtonView(); $button->setText(pht("Show All Tags")); $button->setTag('a'); $button->setIcon($icon); $button->setHref($drequest->generateURI( array( 'action' => 'tags', ))); $header->addActionLink($button); $panel->setHeader($header); $panel->appendChild($view); return $panel; } private function buildActionList(PhabricatorRepository $repository) { $viewer = $this->getRequest()->getUser(); $view_uri = $this->getApplicationURI($repository->getCallsign().'/'); $edit_uri = $this->getApplicationURI($repository->getCallsign().'/edit/'); $view = id(new PhabricatorActionListView()) ->setUser($viewer) ->setObject($repository) ->setObjectURI($view_uri); $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, $repository, PhabricatorPolicyCapability::CAN_EDIT); $view->addAction( id(new PhabricatorActionView()) ->setName(pht('Edit Repository')) ->setIcon('fa-pencil') ->setHref($edit_uri) ->setWorkflow(!$can_edit) ->setDisabled(!$can_edit)); if ($repository->isHosted()) { $callsign = $repository->getCallsign(); $push_uri = $this->getApplicationURI( 'pushlog/?repositories=r'.$callsign); $view->addAction( id(new PhabricatorActionView()) ->setName(pht('View Push Logs')) ->setIcon('fa-list-alt') ->setHref($push_uri)); } return $view; } private function buildHistoryTable( $history_results, $history, $history_exception, array $handles) { $request = $this->getRequest(); $viewer = $request->getUser(); $drequest = $this->getDiffusionRequest(); $repository = $drequest->getRepository(); if ($history_exception) { if ($repository->isImporting()) { return $this->renderStatusMessage( pht('Still Importing...'), pht( 'This repository is still importing. History is not yet '. 'available.')); } else { return $this->renderStatusMessage( pht('Unable to Retrieve History'), $history_exception->getMessage()); } } $history_table = id(new DiffusionHistoryTableView()) ->setUser($viewer) ->setDiffusionRequest($drequest) ->setHandles($handles) ->setHistory($history); // TODO: Super sketchy. $history_table->loadRevisions(); if ($history_results) { $history_table->setParents($history_results['parents']); } $history_table->setIsHead(true); $callsign = $drequest->getRepository()->getCallsign(); $icon = id(new PHUIIconView()) ->setIconFont('fa-list-alt'); $button = id(new PHUIButtonView()) ->setText(pht('View Full History')) ->setHref($drequest->generateURI( array( 'action' => 'history', ))) ->setTag('a') ->setIcon($icon); $panel = new PHUIObjectBoxView(); $header = id(new PHUIHeaderView()) ->setHeader(pht('Recent Commits')) ->addActionLink($button); $panel->setHeader($header); $panel->appendChild($history_table); return $panel; } private function buildBrowseTable( $browse_results, $browse_paths, $browse_exception, array $handles) { $request = $this->getRequest(); $viewer = $request->getUser(); $drequest = $this->getDiffusionRequest(); $repository = $drequest->getRepository(); if ($browse_exception) { if ($repository->isImporting()) { // The history table renders a useful message. return null; } else { return $this->renderStatusMessage( pht('Unable to Retrieve Paths'), $browse_exception->getMessage()); } } $browse_table = id(new DiffusionBrowseTableView()) ->setUser($viewer) ->setDiffusionRequest($drequest) ->setHandles($handles); if ($browse_paths) { $browse_table->setPaths($browse_paths); } else { $browse_table->setPaths(array()); } $browse_uri = $drequest->generateURI(array('action' => 'browse')); $browse_panel = new PHUIObjectBoxView(); $header = id(new PHUIHeaderView()) ->setHeader(pht('Repository')); $icon = id(new PHUIIconView()) ->setIconFont('fa-folder-open'); $button = new PHUIButtonView(); $button->setText(pht('Browse Repository')); $button->setTag('a'); $button->setIcon($icon); $button->setHref($browse_uri); $header->addActionLink($button); $browse_panel->setHeader($header); if ($repository->canUsePathTree()) { Javelin::initBehavior( 'diffusion-locate-file', array( 'controlID' => 'locate-control', 'inputID' => 'locate-input', 'browseBaseURI' => (string)$drequest->generateURI( array( 'action' => 'browse', )), 'uri' => (string)$drequest->generateURI( array( 'action' => 'pathtree', )), )); $form = id(new AphrontFormView()) ->setUser($viewer) ->appendChild( id(new AphrontFormTypeaheadControl()) ->setHardpointID('locate-control') ->setID('locate-input') ->setLabel(pht('Locate File'))); $browse_panel->appendChild($form->buildLayoutView()); } $browse_panel->appendChild($browse_table); return $browse_panel; } private function renderCloneCommand( PhabricatorRepository $repository, $uri, $serve_mode = null, $manage_uri = null) { require_celerity_resource('diffusion-icons-css'); Javelin::initBehavior('select-on-click'); switch ($repository->getVersionControlSystem()) { case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: $command = csprintf( 'git clone %R', $uri); break; case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: $command = csprintf( 'hg clone %R', $uri); break; case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: if ($repository->isHosted()) { $command = csprintf( 'svn checkout %R %R', $uri, $repository->getCloneName()); } else { $command = csprintf( 'svn checkout %R', $uri); } break; } $input = javelin_tag( 'input', array( 'type' => 'text', 'value' => (string)$command, 'class' => 'diffusion-clone-uri', 'sigil' => 'select-on-click', 'readonly' => 'true', )); $extras = array(); if ($serve_mode) { if ($serve_mode === PhabricatorRepository::SERVE_READONLY) { $extras[] = pht('(Read Only)'); } } if ($manage_uri) { if ($this->getRequest()->getUser()->isLoggedIn()) { $extras[] = phutil_tag( 'a', array( 'href' => $manage_uri, ), pht('Manage Credentials')); } } if ($extras) { $extras = phutil_implode_html(' ', $extras); $extras = phutil_tag( 'div', array( 'class' => 'diffusion-clone-extras', ), $extras); } return array($input, $extras); } } diff --git a/src/applications/diffusion/controller/DiffusionRepositoryEditMainController.php b/src/applications/diffusion/controller/DiffusionRepositoryEditMainController.php index 50a74dd376..c70ce57e5a 100644 --- a/src/applications/diffusion/controller/DiffusionRepositoryEditMainController.php +++ b/src/applications/diffusion/controller/DiffusionRepositoryEditMainController.php @@ -1,1121 +1,1121 @@ <?php final class DiffusionRepositoryEditMainController extends DiffusionRepositoryEditController { public function processRequest() { $request = $this->getRequest(); $viewer = $request->getUser(); $drequest = $this->diffusionRequest; $repository = $drequest->getRepository(); PhabricatorPolicyFilter::requireCapability( $viewer, $repository, PhabricatorPolicyCapability::CAN_EDIT); $is_svn = false; $is_git = false; $is_hg = false; switch ($repository->getVersionControlSystem()) { case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: $is_git = true; break; case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: $is_svn = true; break; case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: $is_hg = true; break; } $has_branches = ($is_git || $is_hg); $has_local = $repository->usesLocalWorkingCopy(); $crumbs = $this->buildApplicationCrumbs($is_main = true); $title = pht('Edit %s', $repository->getName()); $header = id(new PHUIHeaderView()) ->setHeader($title); if ($repository->isTracked()) { - $header->setStatus('oh-ok', '', pht('Active')); + $header->setStatus('fa-check', 'bluegrey', pht('Active')); } else { - $header->setStatus('policy-noone', '', pht('Inactive')); + $header->setStatus('fa-ban', 'dark', pht('Inactive')); } $basic_actions = $this->buildBasicActions($repository); $basic_properties = $this->buildBasicProperties($repository, $basic_actions); $policy_actions = $this->buildPolicyActions($repository); $policy_properties = $this->buildPolicyProperties($repository, $policy_actions); $remote_properties = null; if (!$repository->isHosted()) { $remote_properties = $this->buildRemoteProperties( $repository, $this->buildRemoteActions($repository)); } $encoding_actions = $this->buildEncodingActions($repository); $encoding_properties = $this->buildEncodingProperties($repository, $encoding_actions); $hosting_properties = $this->buildHostingProperties( $repository, $this->buildHostingActions($repository)); $branches_properties = null; if ($has_branches) { $branches_properties = $this->buildBranchesProperties( $repository, $this->buildBranchesActions($repository)); } $subversion_properties = null; if ($is_svn) { $subversion_properties = $this->buildSubversionProperties( $repository, $this->buildSubversionActions($repository)); } $local_properties = null; if ($has_local) { $local_properties = $this->buildLocalProperties( $repository, $this->buildLocalActions($repository)); } $actions_properties = $this->buildActionsProperties( $repository, $this->buildActionsActions($repository)); $xactions = id(new PhabricatorRepositoryTransactionQuery()) ->setViewer($viewer) ->withObjectPHIDs(array($repository->getPHID())) ->execute(); $engine = id(new PhabricatorMarkupEngine()) ->setViewer($viewer); foreach ($xactions as $xaction) { if ($xaction->getComment()) { $engine->addObject( $xaction->getComment(), PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT); } } $engine->process(); $xaction_view = id(new PhabricatorApplicationTransactionView()) ->setUser($viewer) ->setObjectPHID($repository->getPHID()) ->setTransactions($xactions) ->setMarkupEngine($engine); $boxes = array(); $boxes[] = id(new PHUIObjectBoxView()) ->setHeader($header) ->addPropertyList($basic_properties); $boxes[] = id(new PHUIObjectBoxView()) ->setHeaderText(pht('Policies')) ->addPropertyList($policy_properties); $boxes[] = id(new PHUIObjectBoxView()) ->setHeaderText(pht('Hosting')) ->addPropertyList($hosting_properties); if ($repository->canMirror()) { $mirror_actions = $this->buildMirrorActions($repository); $mirror_properties = $this->buildMirrorProperties( $repository, $mirror_actions); $mirrors = id(new PhabricatorRepositoryMirrorQuery()) ->setViewer($viewer) ->withRepositoryPHIDs(array($repository->getPHID())) ->execute(); $mirror_list = $this->buildMirrorList($repository, $mirrors); $boxes[] = id(new PhabricatorAnchorView())->setAnchorName('mirrors'); $boxes[] = id(new PHUIObjectBoxView()) ->setHeaderText(pht('Mirrors')) ->addPropertyList($mirror_properties); $boxes[] = $mirror_list; } if ($remote_properties) { $boxes[] = id(new PHUIObjectBoxView()) ->setHeaderText(pht('Remote')) ->addPropertyList($remote_properties); } if ($local_properties) { $boxes[] = id(new PHUIObjectBoxView()) ->setHeaderText(pht('Local')) ->addPropertyList($local_properties); } $boxes[] = id(new PHUIObjectBoxView()) ->setHeaderText(pht('Text Encoding')) ->addPropertyList($encoding_properties); if ($branches_properties) { $boxes[] = id(new PHUIObjectBoxView()) ->setHeaderText(pht('Branches')) ->addPropertyList($branches_properties); } if ($subversion_properties) { $boxes[] = id(new PHUIObjectBoxView()) ->setHeaderText(pht('Subversion')) ->addPropertyList($subversion_properties); } $boxes[] = id(new PHUIObjectBoxView()) ->setHeaderText(pht('Actions')) ->addPropertyList($actions_properties); return $this->buildApplicationPage( array( $crumbs, $boxes, $xaction_view, ), array( 'title' => $title, 'device' => true, )); } private function buildBasicActions(PhabricatorRepository $repository) { $viewer = $this->getRequest()->getUser(); $view = id(new PhabricatorActionListView()) ->setObjectURI($this->getRequest()->getRequestURI()) ->setUser($viewer); $edit = id(new PhabricatorActionView()) ->setIcon('fa-pencil') ->setName(pht('Edit Basic Information')) ->setHref($this->getRepositoryControllerURI($repository, 'edit/basic/')); $view->addAction($edit); $activate = id(new PhabricatorActionView()) ->setHref( $this->getRepositoryControllerURI($repository, 'edit/activate/')) ->setWorkflow(true); if ($repository->isTracked()) { $activate ->setIcon('fa-pause') ->setName(pht('Deactivate Repository')); } else { $activate ->setIcon('fa-play') ->setName(pht('Activate Repository')); } $view->addAction($activate); $view->addAction( id(new PhabricatorActionView()) ->setName(pht('Delete Repository')) ->setIcon('fa-times') ->setHref( $this->getRepositoryControllerURI($repository, 'edit/delete/')) ->setDisabled(true) ->setWorkflow(true)); return $view; } private function buildBasicProperties( PhabricatorRepository $repository, PhabricatorActionListView $actions) { $viewer = $this->getRequest()->getUser(); $view = id(new PHUIPropertyListView()) ->setUser($viewer) ->setActionList($actions); $type = PhabricatorRepositoryType::getNameForRepositoryType( $repository->getVersionControlSystem()); $view->addProperty(pht('Type'), $type); $view->addProperty(pht('Callsign'), $repository->getCallsign()); $clone_name = $repository->getDetail('clone-name'); if ($repository->isHosted()) { $view->addProperty( pht('Clone/Checkout As'), $clone_name ? $clone_name.'/' : phutil_tag('em', array(), $repository->getCloneName().'/')); } $project_phids = PhabricatorEdgeQuery::loadDestinationPHIDs( $repository->getPHID(), PhabricatorEdgeConfig::TYPE_OBJECT_HAS_PROJECT); if ($project_phids) { $this->loadHandles($project_phids); $project_text = $this->renderHandlesForPHIDs($project_phids); } else { $project_text = phutil_tag('em', array(), pht('None')); } $view->addProperty( pht('Projects'), $project_text); $view->addProperty( pht('Status'), $this->buildRepositoryStatus($repository)); $description = $repository->getDetail('description'); $view->addSectionHeader(pht('Description')); if (!strlen($description)) { $description = phutil_tag('em', array(), pht('No description provided.')); } else { $description = PhabricatorMarkupEngine::renderOneObject( $repository, 'description', $viewer); } $view->addTextContent($description); return $view; } private function buildEncodingActions(PhabricatorRepository $repository) { $viewer = $this->getRequest()->getUser(); $view = id(new PhabricatorActionListView()) ->setObjectURI($this->getRequest()->getRequestURI()) ->setUser($viewer); $edit = id(new PhabricatorActionView()) ->setIcon('fa-pencil') ->setName(pht('Edit Text Encoding')) ->setHref( $this->getRepositoryControllerURI($repository, 'edit/encoding/')); $view->addAction($edit); return $view; } private function buildEncodingProperties( PhabricatorRepository $repository, PhabricatorActionListView $actions) { $viewer = $this->getRequest()->getUser(); $view = id(new PHUIPropertyListView()) ->setUser($viewer) ->setActionList($actions); $encoding = $repository->getDetail('encoding'); if (!$encoding) { $encoding = phutil_tag('em', array(), pht('Use Default (UTF-8)')); } $view->addProperty(pht('Encoding'), $encoding); return $view; } private function buildPolicyActions(PhabricatorRepository $repository) { $viewer = $this->getRequest()->getUser(); $view = id(new PhabricatorActionListView()) ->setObjectURI($this->getRequest()->getRequestURI()) ->setUser($viewer); $edit = id(new PhabricatorActionView()) ->setIcon('fa-pencil') ->setName(pht('Edit Policies')) ->setHref( $this->getRepositoryControllerURI($repository, 'edit/policy/')); $view->addAction($edit); return $view; } private function buildPolicyProperties( PhabricatorRepository $repository, PhabricatorActionListView $actions) { $viewer = $this->getRequest()->getUser(); $view = id(new PHUIPropertyListView()) ->setUser($viewer) ->setActionList($actions); $descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions( $viewer, $repository); $view->addProperty( pht('Visible To'), $descriptions[PhabricatorPolicyCapability::CAN_VIEW]); $view->addProperty( pht('Editable By'), $descriptions[PhabricatorPolicyCapability::CAN_EDIT]); $pushable = $repository->isHosted() ? $descriptions[DiffusionCapabilityPush::CAPABILITY] : phutil_tag('em', array(), pht('Not a Hosted Repository')); $view->addProperty(pht('Pushable By'), $pushable); return $view; } private function buildBranchesActions(PhabricatorRepository $repository) { $viewer = $this->getRequest()->getUser(); $view = id(new PhabricatorActionListView()) ->setObjectURI($this->getRequest()->getRequestURI()) ->setUser($viewer); $edit = id(new PhabricatorActionView()) ->setIcon('fa-pencil') ->setName(pht('Edit Branches')) ->setHref( $this->getRepositoryControllerURI($repository, 'edit/branches/')); $view->addAction($edit); return $view; } private function buildBranchesProperties( PhabricatorRepository $repository, PhabricatorActionListView $actions) { $viewer = $this->getRequest()->getUser(); $view = id(new PHUIPropertyListView()) ->setUser($viewer) ->setActionList($actions); $default_branch = nonempty( $repository->getHumanReadableDetail('default-branch'), phutil_tag('em', array(), $repository->getDefaultBranch())); $view->addProperty(pht('Default Branch'), $default_branch); $track_only = nonempty( $repository->getHumanReadableDetail('branch-filter', array()), phutil_tag('em', array(), pht('Track All Branches'))); $view->addProperty(pht('Track Only'), $track_only); $autoclose_only = nonempty( $repository->getHumanReadableDetail('close-commits-filter', array()), phutil_tag('em', array(), pht('Autoclose On All Branches'))); if ($repository->getDetail('disable-autoclose')) { $autoclose_only = phutil_tag('em', array(), pht('Disabled')); } $view->addProperty(pht('Autoclose Only'), $autoclose_only); return $view; } private function buildSubversionActions(PhabricatorRepository $repository) { $viewer = $this->getRequest()->getUser(); $view = id(new PhabricatorActionListView()) ->setObjectURI($this->getRequest()->getRequestURI()) ->setUser($viewer); $edit = id(new PhabricatorActionView()) ->setIcon('fa-pencil') ->setName(pht('Edit Subversion Info')) ->setHref( $this->getRepositoryControllerURI($repository, 'edit/subversion/')); $view->addAction($edit); return $view; } private function buildSubversionProperties( PhabricatorRepository $repository, PhabricatorActionListView $actions) { $viewer = $this->getRequest()->getUser(); $view = id(new PHUIPropertyListView()) ->setUser($viewer) ->setActionList($actions); $svn_uuid = nonempty( $repository->getUUID(), phutil_tag('em', array(), pht('Not Configured'))); $view->addProperty(pht('Subversion UUID'), $svn_uuid); $svn_subpath = nonempty( $repository->getHumanReadableDetail('svn-subpath'), phutil_tag('em', array(), pht('Import Entire Repository'))); $view->addProperty(pht('Import Only'), $svn_subpath); return $view; } private function buildActionsActions(PhabricatorRepository $repository) { $viewer = $this->getRequest()->getUser(); $view = id(new PhabricatorActionListView()) ->setObjectURI($this->getRequest()->getRequestURI()) ->setUser($viewer); $edit = id(new PhabricatorActionView()) ->setIcon('fa-pencil') ->setName(pht('Edit Actions')) ->setHref( $this->getRepositoryControllerURI($repository, 'edit/actions/')); $view->addAction($edit); return $view; } private function buildActionsProperties( PhabricatorRepository $repository, PhabricatorActionListView $actions) { $viewer = $this->getRequest()->getUser(); $view = id(new PHUIPropertyListView()) ->setUser($viewer) ->setActionList($actions); $notify = $repository->getDetail('herald-disabled') ? pht('Off') : pht('On'); $notify = phutil_tag('em', array(), $notify); $view->addProperty(pht('Publish/Notify'), $notify); $autoclose = $repository->getDetail('disable-autoclose') ? pht('Off') : pht('On'); $autoclose = phutil_tag('em', array(), $autoclose); $view->addProperty(pht('Autoclose'), $autoclose); return $view; } private function buildRemoteActions(PhabricatorRepository $repository) { $viewer = $this->getRequest()->getUser(); $view = id(new PhabricatorActionListView()) ->setObjectURI($this->getRequest()->getRequestURI()) ->setUser($viewer); $edit = id(new PhabricatorActionView()) ->setIcon('fa-pencil') ->setName(pht('Edit Remote')) ->setHref( $this->getRepositoryControllerURI($repository, 'edit/remote/')); $view->addAction($edit); return $view; } private function buildRemoteProperties( PhabricatorRepository $repository, PhabricatorActionListView $actions) { $viewer = $this->getRequest()->getUser(); $view = id(new PHUIPropertyListView()) ->setUser($viewer) ->setActionList($actions); $view->addProperty( pht('Remote URI'), $repository->getHumanReadableDetail('remote-uri')); $credential_phid = $repository->getCredentialPHID(); if ($credential_phid) { $this->loadHandles(array($credential_phid)); $view->addProperty( pht('Credential'), $this->getHandle($credential_phid)->renderLink()); } return $view; } private function buildLocalActions(PhabricatorRepository $repository) { $viewer = $this->getRequest()->getUser(); $view = id(new PhabricatorActionListView()) ->setObjectURI($this->getRequest()->getRequestURI()) ->setUser($viewer); $edit = id(new PhabricatorActionView()) ->setIcon('fa-pencil') ->setName(pht('Edit Local')) ->setHref( $this->getRepositoryControllerURI($repository, 'edit/local/')); $view->addAction($edit); return $view; } private function buildLocalProperties( PhabricatorRepository $repository, PhabricatorActionListView $actions) { $viewer = $this->getRequest()->getUser(); $view = id(new PHUIPropertyListView()) ->setUser($viewer) ->setActionList($actions); $view->addProperty( pht('Local Path'), $repository->getHumanReadableDetail('local-path')); return $view; } private function buildHostingActions(PhabricatorRepository $repository) { $user = $this->getRequest()->getUser(); $view = id(new PhabricatorActionListView()) ->setObjectURI($this->getRequest()->getRequestURI()) ->setUser($user); $edit = id(new PhabricatorActionView()) ->setIcon('fa-pencil') ->setName(pht('Edit Hosting')) ->setHref( $this->getRepositoryControllerURI($repository, 'edit/hosting/')); $view->addAction($edit); if ($repository->canAllowDangerousChanges()) { if ($repository->shouldAllowDangerousChanges()) { $changes = id(new PhabricatorActionView()) ->setIcon('fa-shield') ->setName(pht('Prevent Dangerous Changes')) ->setHref( $this->getRepositoryControllerURI($repository, 'edit/dangerous/')) ->setWorkflow(true); } else { $changes = id(new PhabricatorActionView()) ->setIcon('fa-bullseye') ->setName(pht('Allow Dangerous Changes')) ->setHref( $this->getRepositoryControllerURI($repository, 'edit/dangerous/')) ->setWorkflow(true); } $view->addAction($changes); } return $view; } private function buildHostingProperties( PhabricatorRepository $repository, PhabricatorActionListView $actions) { $user = $this->getRequest()->getUser(); $view = id(new PHUIPropertyListView()) ->setUser($user) ->setActionList($actions); $hosting = $repository->isHosted() ? pht('Hosted on Phabricator') : pht('Hosted Elsewhere'); $view->addProperty(pht('Hosting'), phutil_tag('em', array(), $hosting)); $view->addProperty( pht('Serve over HTTP'), phutil_tag( 'em', array(), PhabricatorRepository::getProtocolAvailabilityName( $repository->getServeOverHTTP()))); $view->addProperty( pht('Serve over SSH'), phutil_tag( 'em', array(), PhabricatorRepository::getProtocolAvailabilityName( $repository->getServeOverSSH()))); if ($repository->canAllowDangerousChanges()) { if ($repository->shouldAllowDangerousChanges()) { $description = pht('Allowed'); } else { $description = pht('Not Allowed'); } $view->addProperty( pht('Dangerous Changes'), $description); } return $view; } private function buildRepositoryStatus( PhabricatorRepository $repository) { $viewer = $this->getRequest()->getUser(); $view = new PHUIStatusListView(); $messages = id(new PhabricatorRepositoryStatusMessage()) ->loadAllWhere('repositoryID = %d', $repository->getID()); $messages = mpull($messages, null, 'getStatusType'); if ($repository->isTracked()) { $view->addItem( id(new PHUIStatusItemView()) ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') ->setTarget(pht('Repository Active'))); } else { $view->addItem( id(new PHUIStatusItemView()) ->setIcon(PHUIStatusItemView::ICON_WARNING, 'bluegrey') ->setTarget(pht('Repository Inactive')) ->setNote( pht('Activate this repository to begin or resume import.'))); return $view; } $binaries = array(); $svnlook_check = false; switch ($repository->getVersionControlSystem()) { case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: $binaries[] = 'git'; break; case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: $binaries[] = 'svn'; break; case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: $binaries[] = 'hg'; break; } if ($repository->isHosted()) { if ($repository->getServeOverHTTP() != PhabricatorRepository::SERVE_OFF) { switch ($repository->getVersionControlSystem()) { case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: $binaries[] = 'git-http-backend'; break; case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: $binaries[] = 'svnserve'; $binaries[] = 'svnadmin'; $binaries[] = 'svnlook'; $svnlook_check = true; break; case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: $binaries[] = 'hg'; break; } } if ($repository->getServeOverSSH() != PhabricatorRepository::SERVE_OFF) { switch ($repository->getVersionControlSystem()) { case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: $binaries[] = 'git-receive-pack'; $binaries[] = 'git-upload-pack'; break; case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: $binaries[] = 'svnserve'; $binaries[] = 'svnadmin'; $binaries[] = 'svnlook'; $svnlook_check = true; break; case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: $binaries[] = 'hg'; break; } } } $binaries = array_unique($binaries); foreach ($binaries as $binary) { $where = Filesystem::resolveBinary($binary); if (!$where) { $view->addItem( id(new PHUIStatusItemView()) ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') ->setTarget( pht('Missing Binary %s', phutil_tag('tt', array(), $binary))) ->setNote(pht( "Unable to find this binary in the webserver's PATH. You may ". "need to configure %s.", $this->getEnvConfigLink()))); } else { $view->addItem( id(new PHUIStatusItemView()) ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') ->setTarget( pht('Found Binary %s', phutil_tag('tt', array(), $binary))) ->setNote(phutil_tag('tt', array(), $where))); } } // This gets checked generically above. However, for svn commit hooks, we // need this to be in environment.append-paths because subversion strips // PATH. if ($svnlook_check) { $where = Filesystem::resolveBinary('svnlook'); if ($where) { $path = substr($where, 0, strlen($where) - strlen('svnlook')); $dirs = PhabricatorEnv::getEnvConfig('environment.append-paths'); $in_path = false; foreach ($dirs as $dir) { if (Filesystem::isDescendant($path, $dir)) { $in_path = true; break; } } if (!$in_path) { $view->addItem( id(new PHUIStatusItemView()) ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') ->setTarget( pht('Missing Binary %s', phutil_tag('tt', array(), $binary))) ->setNote(pht( 'Unable to find this binary in `environment.append-paths`. '. 'You need to configure %s and include %s.', $this->getEnvConfigLink(), $path))); } } } $doc_href = PhabricatorEnv::getDocLink('Managing Daemons with phd'); $daemon_instructions = pht( 'Use %s to start daemons. See %s.', phutil_tag('tt', array(), 'bin/phd start'), phutil_tag( 'a', array( 'href' => $doc_href, ), pht('Managing Daemons with phd'))); $pull_daemon = id(new PhabricatorDaemonLogQuery()) ->setViewer(PhabricatorUser::getOmnipotentUser()) ->withStatus(PhabricatorDaemonLogQuery::STATUS_ALIVE) ->withDaemonClasses(array('PhabricatorRepositoryPullLocalDaemon')) ->setLimit(1) ->execute(); if ($pull_daemon) { $view->addItem( id(new PHUIStatusItemView()) ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') ->setTarget(pht('Pull Daemon Running'))); } else { $view->addItem( id(new PHUIStatusItemView()) ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') ->setTarget(pht('Pull Daemon Not Running')) ->setNote($daemon_instructions)); } $task_daemon = id(new PhabricatorDaemonLogQuery()) ->setViewer(PhabricatorUser::getOmnipotentUser()) ->withStatus(PhabricatorDaemonLogQuery::STATUS_ALIVE) ->withDaemonClasses(array('PhabricatorTaskmasterDaemon')) ->setLimit(1) ->execute(); if ($task_daemon) { $view->addItem( id(new PHUIStatusItemView()) ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') ->setTarget(pht('Task Daemon Running'))); } else { $view->addItem( id(new PHUIStatusItemView()) ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') ->setTarget(pht('Task Daemon Not Running')) ->setNote($daemon_instructions)); } if ($repository->usesLocalWorkingCopy()) { $local_parent = dirname($repository->getLocalPath()); if (Filesystem::pathExists($local_parent)) { $view->addItem( id(new PHUIStatusItemView()) ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') ->setTarget(pht('Storage Directory OK')) ->setNote(phutil_tag('tt', array(), $local_parent))); } else { $view->addItem( id(new PHUIStatusItemView()) ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') ->setTarget(pht('No Storage Directory')) ->setNote( pht( 'Storage directory %s does not exist, or is not readable by '. 'the webserver. Create this directory or make it readable.', phutil_tag('tt', array(), $local_parent)))); return $view; } $local_path = $repository->getLocalPath(); $message = idx($messages, PhabricatorRepositoryStatusMessage::TYPE_INIT); if ($message) { switch ($message->getStatusCode()) { case PhabricatorRepositoryStatusMessage::CODE_ERROR: $view->addItem( id(new PHUIStatusItemView()) ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') ->setTarget(pht('Initialization Error')) ->setNote($message->getParameter('message'))); return $view; case PhabricatorRepositoryStatusMessage::CODE_OKAY: if (Filesystem::pathExists($local_path)) { $view->addItem( id(new PHUIStatusItemView()) ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') ->setTarget(pht('Working Copy OK')) ->setNote(phutil_tag('tt', array(), $local_path))); } else { $view->addItem( id(new PHUIStatusItemView()) ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') ->setTarget(pht('Working Copy Error')) ->setNote( pht( 'Working copy %s has been deleted, or is not '. 'readable by the webserver. Make this directory '. 'readable. If it has been deleted, the daemons should '. 'restore it automatically.', phutil_tag('tt', array(), $local_path)))); return $view; } break; case PhabricatorRepositoryStatusMessage::CODE_WORKING: $view->addItem( id(new PHUIStatusItemView()) ->setIcon(PHUIStatusItemView::ICON_CLOCK, 'green') ->setTarget(pht('Initializing Working Copy')) ->setNote(pht('Daemons are initializing the working copy.'))); return $view; default: $view->addItem( id(new PHUIStatusItemView()) ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') ->setTarget(pht('Unknown Init Status')) ->setNote($message->getStatusCode())); return $view; } } else { $view->addItem( id(new PHUIStatusItemView()) ->setIcon(PHUIStatusItemView::ICON_CLOCK, 'orange') ->setTarget(pht('No Working Copy Yet')) ->setNote( pht('Waiting for daemons to build a working copy.'))); return $view; } } $message = idx($messages, PhabricatorRepositoryStatusMessage::TYPE_FETCH); if ($message) { switch ($message->getStatusCode()) { case PhabricatorRepositoryStatusMessage::CODE_ERROR: $view->addItem( id(new PHUIStatusItemView()) ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') ->setTarget(pht('Update Error')) ->setNote($message->getParameter('message'))); return $view; case PhabricatorRepositoryStatusMessage::CODE_OKAY: $view->addItem( id(new PHUIStatusItemView()) ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') ->setTarget(pht('Updates OK')) ->setNote( pht( 'Last updated %s.', phabricator_datetime($message->getEpoch(), $viewer)))); break; } } else { $view->addItem( id(new PHUIStatusItemView()) ->setIcon(PHUIStatusItemView::ICON_CLOCK, 'orange') ->setTarget(pht('Waiting For Update')) ->setNote( pht('Waiting for daemons to read updates.'))); } if ($repository->isImporting()) { $progress = queryfx_all( $repository->establishConnection('r'), 'SELECT importStatus, count(*) N FROM %T WHERE repositoryID = %d GROUP BY importStatus', id(new PhabricatorRepositoryCommit())->getTableName(), $repository->getID()); $done = 0; $total = 0; foreach ($progress as $row) { $total += $row['N'] * 4; $status = $row['importStatus']; if ($status & PhabricatorRepositoryCommit::IMPORTED_MESSAGE) { $done += $row['N']; } if ($status & PhabricatorRepositoryCommit::IMPORTED_CHANGE) { $done += $row['N']; } if ($status & PhabricatorRepositoryCommit::IMPORTED_OWNERS) { $done += $row['N']; } if ($status & PhabricatorRepositoryCommit::IMPORTED_HERALD) { $done += $row['N']; } } if ($total) { $percentage = 100 * ($done / $total); } else { $percentage = 0; } // Cap this at "99.99%", because it's confusing to users when the actual // fraction is "99.996%" and it rounds up to "100.00%". if ($percentage > 99.99) { $percentage = 99.99; } $percentage = sprintf('%.2f%%', $percentage); $view->addItem( id(new PHUIStatusItemView()) ->setIcon(PHUIStatusItemView::ICON_CLOCK, 'green') ->setTarget(pht('Importing')) ->setNote( pht('%s Complete', $percentage))); } else { $view->addItem( id(new PHUIStatusItemView()) ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') ->setTarget(pht('Fully Imported'))); } if (idx($messages, PhabricatorRepositoryStatusMessage::TYPE_NEEDS_UPDATE)) { $view->addItem( id(new PHUIStatusItemView()) ->setIcon(PHUIStatusItemView::ICON_UP, 'indigo') ->setTarget(pht('Prioritized')) ->setNote(pht('This repository will be updated soon.'))); } return $view; } private function buildMirrorActions( PhabricatorRepository $repository) { $viewer = $this->getRequest()->getUser(); $mirror_actions = id(new PhabricatorActionListView()) ->setObjectURI($this->getRequest()->getRequestURI()) ->setUser($viewer); $new_mirror_uri = $this->getRepositoryControllerURI( $repository, 'mirror/edit/'); $mirror_actions->addAction( id(new PhabricatorActionView()) ->setName(pht('Add Mirror')) ->setIcon('fa-plus') ->setHref($new_mirror_uri) ->setWorkflow(true)); return $mirror_actions; } private function buildMirrorProperties( PhabricatorRepository $repository, PhabricatorActionListView $actions) { $viewer = $this->getRequest()->getUser(); $mirror_properties = id(new PHUIPropertyListView()) ->setUser($viewer) ->setActionList($actions); $mirror_properties->addProperty( '', phutil_tag( 'em', array(), pht('Automatically push changes into other remotes.'))); return $mirror_properties; } private function buildMirrorList( PhabricatorRepository $repository, array $mirrors) { assert_instances_of($mirrors, 'PhabricatorRepositoryMirror'); $mirror_list = id(new PHUIObjectItemListView()) ->setNoDataString(pht('This repository has no configured mirrors.')); foreach ($mirrors as $mirror) { $item = id(new PHUIObjectItemView()) ->setHeader($mirror->getRemoteURI()); $edit_uri = $this->getRepositoryControllerURI( $repository, 'mirror/edit/'.$mirror->getID().'/'); $delete_uri = $this->getRepositoryControllerURI( $repository, 'mirror/delete/'.$mirror->getID().'/'); $item->addAction( id(new PHUIListItemView()) ->setIcon('fa-pencil') ->setHref($edit_uri) ->setWorkflow(true)); $item->addAction( id(new PHUIListItemView()) ->setIcon('fa-times') ->setHref($delete_uri) ->setWorkflow(true)); $mirror_list->addItem($item); } return $mirror_list; } private function getEnvConfigLink() { $config_href = '/config/edit/environment.append-paths/'; return phutil_tag( 'a', array( 'href' => $config_href, ), 'environment.append-paths'); } } diff --git a/src/applications/harbormaster/controller/HarbormasterBuildViewController.php b/src/applications/harbormaster/controller/HarbormasterBuildViewController.php index d3aadcec13..a459240234 100644 --- a/src/applications/harbormaster/controller/HarbormasterBuildViewController.php +++ b/src/applications/harbormaster/controller/HarbormasterBuildViewController.php @@ -1,376 +1,376 @@ <?php final class HarbormasterBuildViewController extends HarbormasterController { private $id; public function willProcessRequest(array $data) { $this->id = $data['id']; } public function processRequest() { $request = $this->getRequest(); $viewer = $request->getUser(); $id = $this->id; $build = id(new HarbormasterBuildQuery()) ->setViewer($viewer) ->withIDs(array($id)) ->executeOne(); if (!$build) { return new Aphront404Response(); } $title = pht("Build %d", $id); $header = id(new PHUIHeaderView()) ->setHeader($title) ->setUser($viewer) ->setPolicyObject($build); if ($build->isRestarting()) { - $header->setStatus('warning', 'red', pht('Restarting')); + $header->setStatus('fa-exclamation-triangle', 'red', pht('Restarting')); } else if ($build->isStopping()) { - $header->setStatus('warning', 'red', pht('Stopping')); + $header->setStatus('fa-exclamation-triangle', 'red', pht('Stopping')); } else if ($build->isResuming()) { - $header->setStatus('warning', 'red', pht('Resuming')); + $header->setStatus('fa-exclamation-triangle', 'red', pht('Resuming')); } $box = id(new PHUIObjectBoxView()) ->setHeader($header); $actions = $this->buildActionList($build); $this->buildPropertyLists($box, $build, $actions); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb( $build->getBuildable()->getMonogram(), '/'.$build->getBuildable()->getMonogram()); $crumbs->addTextCrumb($title); $build_targets = id(new HarbormasterBuildTargetQuery()) ->setViewer($viewer) ->withBuildPHIDs(array($build->getPHID())) ->execute(); if ($build_targets) { $messages = id(new HarbormasterBuildMessageQuery()) ->setViewer($viewer) ->withBuildTargetPHIDs(mpull($build_targets, 'getPHID')) ->execute(); $messages = mgroup($messages, 'getBuildTargetPHID'); } else { $messages = array(); } $targets = array(); foreach ($build_targets as $build_target) { $header = id(new PHUIHeaderView()) ->setHeader(pht( 'Build Target %d (%s)', $build_target->getID(), $build_target->getImplementation()->getName())) ->setUser($viewer); $properties = new PHUIPropertyListView(); $details = $build_target->getDetails(); if ($details) { $properties->addSectionHeader(pht('Configuration Details')); foreach ($details as $key => $value) { $properties->addProperty($key, $value); } } $variables = $build_target->getVariables(); if ($variables) { $properties->addSectionHeader(pht('Variables')); foreach ($variables as $key => $value) { $properties->addProperty($key, $value); } } $targets[] = id(new PHUIObjectBoxView()) ->setHeader($header) ->addPropertyList($properties); $build_messages = idx($messages, $build_target->getPHID(), array()); $targets[] = $this->buildMessages($build_messages); $targets[] = $this->buildArtifacts($build_target); $targets[] = $this->buildLog($build, $build_target); } $xactions = id(new HarbormasterBuildTransactionQuery()) ->setViewer($viewer) ->withObjectPHIDs(array($build->getPHID())) ->execute(); $timeline = id(new PhabricatorApplicationTransactionView()) ->setUser($viewer) ->setObjectPHID($build->getPHID()) ->setTransactions($xactions); return $this->buildApplicationPage( array( $crumbs, $box, $targets, $timeline, ), array( 'title' => $title, 'device' => true, )); } private function buildArtifacts(HarbormasterBuildTarget $build_target) { $request = $this->getRequest(); $viewer = $request->getUser(); $artifacts = id(new HarbormasterBuildArtifactQuery()) ->setViewer($viewer) ->withBuildTargetPHIDs(array($build_target->getPHID())) ->execute(); if (count($artifacts) === 0) { return null; } $list = new PHUIObjectItemListView(); foreach ($artifacts as $artifact) { $list->addItem($artifact->getObjectItemView($viewer)); } $header = id(new PHUIHeaderView()) ->setHeader(pht('Build Artifacts')) ->setUser($viewer); $box = id(new PHUIObjectBoxView()) ->setHeader($header); return array($box, $list); } private function buildLog( HarbormasterBuild $build, HarbormasterBuildTarget $build_target) { $request = $this->getRequest(); $viewer = $request->getUser(); $limit = $request->getInt('l', 25); $logs = id(new HarbormasterBuildLogQuery()) ->setViewer($viewer) ->withBuildTargetPHIDs(array($build_target->getPHID())) ->execute(); $log_boxes = array(); foreach ($logs as $log) { $start = 1; $lines = preg_split("/\r\n|\r|\n/", $log->getLogText()); if ($limit !== 0) { $start = count($lines) - $limit; if ($start >= 1) { $lines = array_slice($lines, -$limit, $limit); } else { $start = 1; } } $log_view = new ShellLogView(); $log_view->setLines($lines); $log_view->setStart($start); $header = id(new PHUIHeaderView()) ->setHeader(pht( 'Build Log %d (%s - %s)', $log->getID(), $log->getLogSource(), $log->getLogType())) ->setSubheader($this->createLogHeader($build, $log)) ->setUser($viewer); $log_boxes[] = id(new PHUIObjectBoxView()) ->setHeader($header) ->setForm($log_view); } return $log_boxes; } private function createLogHeader($build, $log) { $request = $this->getRequest(); $limit = $request->getInt('l', 25); $lines_25 = $this->getApplicationURI('/build/'.$build->getID().'/?l=25'); $lines_50 = $this->getApplicationURI('/build/'.$build->getID().'/?l=50'); $lines_100 = $this->getApplicationURI('/build/'.$build->getID().'/?l=100'); $lines_0 = $this->getApplicationURI('/build/'.$build->getID().'/?l=0'); $link_25 = phutil_tag('a', array('href' => $lines_25), pht('25')); $link_50 = phutil_tag('a', array('href' => $lines_50), pht('50')); $link_100 = phutil_tag('a', array('href' => $lines_100), pht('100')); $link_0 = phutil_tag('a', array('href' => $lines_0), pht('Unlimited')); if ($limit === 25) { $link_25 = phutil_tag('strong', array(), $link_25); } else if ($limit === 50) { $link_50 = phutil_tag('strong', array(), $link_50); } else if ($limit === 100) { $link_100 = phutil_tag('strong', array(), $link_100); } else if ($limit === 0) { $link_0 = phutil_tag('strong', array(), $link_0); } return phutil_tag( 'span', array(), array( $link_25, ' - ', $link_50, ' - ', $link_100, ' - ', $link_0, ' Lines')); } private function buildActionList(HarbormasterBuild $build) { $request = $this->getRequest(); $viewer = $request->getUser(); $id = $build->getID(); $list = id(new PhabricatorActionListView()) ->setUser($viewer) ->setObject($build) ->setObjectURI("/build/{$id}"); $can_restart = $build->canRestartBuild(); $can_stop = $build->canStopBuild(); $can_resume = $build->canResumeBuild(); $list->addAction( id(new PhabricatorActionView()) ->setName(pht('Restart Build')) ->setIcon('fa-backward') ->setHref($this->getApplicationURI('/build/restart/'.$id.'/')) ->setDisabled(!$can_restart) ->setWorkflow(true)); $list->addAction( id(new PhabricatorActionView()) ->setName(pht('Stop Build')) ->setIcon('fa-stop') ->setHref($this->getApplicationURI('/build/stop/'.$id.'/')) ->setDisabled(!$can_stop) ->setWorkflow(true)); $list->addAction( id(new PhabricatorActionView()) ->setName(pht('Resume Build')) ->setIcon('fa-play') ->setHref($this->getApplicationURI('/build/resume/'.$id.'/')) ->setDisabled(!$can_resume) ->setWorkflow(true)); return $list; } private function buildPropertyLists( PHUIObjectBoxView $box, HarbormasterBuild $build, PhabricatorActionListView $actions) { $request = $this->getRequest(); $viewer = $request->getUser(); $properties = id(new PHUIPropertyListView()) ->setUser($viewer) ->setObject($build) ->setActionList($actions); $box->addPropertyList($properties); $properties->addProperty( pht('Status'), $this->getStatus($build)); $handles = id(new PhabricatorHandleQuery()) ->setViewer($viewer) ->withPHIDs(array( $build->getBuildablePHID(), $build->getBuildPlanPHID())) ->execute(); $properties->addProperty( pht('Buildable'), $handles[$build->getBuildablePHID()]->renderLink()); $properties->addProperty( pht('Build Plan'), $handles[$build->getBuildPlanPHID()]->renderLink()); } private function getStatus(HarbormasterBuild $build) { if ($build->isStopping()) { return pht('Stopping'); } return HarbormasterBuild::getBuildStatusName($build->getBuildStatus()); } private function buildMessages(array $messages) { $viewer = $this->getRequest()->getUser(); if ($messages) { $handles = id(new PhabricatorHandleQuery()) ->setViewer($viewer) ->withPHIDs(mpull($messages, 'getAuthorPHID')) ->execute(); } else { $handles = array(); } $rows = array(); foreach ($messages as $message) { $rows[] = array( $message->getID(), $handles[$message->getAuthorPHID()]->renderLink(), $message->getType(), $message->getIsConsumed() ? pht('Consumed') : null, phabricator_datetime($message->getDateCreated(), $viewer), ); } $table = new AphrontTableView($rows); $table->setNoDataString(pht('No messages for this build target.')); $table->setHeaders( array( pht('ID'), pht('From'), pht('Type'), pht('Consumed'), pht('Received'), )); $table->setColumnClasses( array( '', '', 'wide', '', 'date', )); $box = id(new PHUIObjectBoxView()) ->setHeaderText(pht('Build Target Messages')) ->appendChild($table); return $box; } } diff --git a/src/applications/harbormaster/query/HarbormasterBuildableSearchEngine.php b/src/applications/harbormaster/query/HarbormasterBuildableSearchEngine.php index 4bb38230c6..4486da3a1e 100644 --- a/src/applications/harbormaster/query/HarbormasterBuildableSearchEngine.php +++ b/src/applications/harbormaster/query/HarbormasterBuildableSearchEngine.php @@ -1,231 +1,231 @@ <?php final class HarbormasterBuildableSearchEngine extends PhabricatorApplicationSearchEngine { public function getApplicationClassName() { return 'PhabricatorApplicationHarbormaster'; } public function buildSavedQueryFromRequest(AphrontRequest $request) { $saved = new PhabricatorSavedQuery(); $revisions = $this->readPHIDsFromRequest( $request, 'revisions', array( DifferentialPHIDTypeRevision::TYPECONST, )); $repositories = $this->readPHIDsFromRequest( $request, 'repositories', array( PhabricatorRepositoryPHIDTypeRepository::TYPECONST, )); $container_phids = array_merge($revisions, $repositories); $saved->setParameter('containerPHIDs', $container_phids); $commits = $this->readPHIDsFromRequest( $request, 'commits', array( PhabricatorRepositoryPHIDTypeCommit::TYPECONST, )); $diffs = $this->readListFromRequest($request, 'diffs'); if ($diffs) { $diffs = id(new DifferentialDiffQuery()) ->setViewer($this->requireViewer()) ->withIDs($diffs) ->execute(); $diffs = mpull($diffs, 'getPHID', 'getPHID'); } $buildable_phids = array_merge($commits, $diffs); $saved->setParameter('buildablePHIDs', $buildable_phids); $saved->setParameter( 'manual', $this->readBoolFromRequest($request, 'manual')); return $saved; } public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { $query = id(new HarbormasterBuildableQuery()) ->needContainerHandles(true) ->needBuildableHandles(true); $container_phids = $saved->getParameter('containerPHIDs', array()); if ($container_phids) { $query->withContainerPHIDs($container_phids); } $buildable_phids = $saved->getParameter('buildablePHIDs', array()); if ($buildable_phids) { $query->withBuildablePHIDs($buildable_phids); } $manual = $saved->getParameter('manual'); if ($manual !== null) { $query->withManualBuildables($manual); } return $query; } public function buildSearchForm( AphrontFormView $form, PhabricatorSavedQuery $saved_query) { $container_phids = $saved_query->getParameter('containerPHIDs', array()); $buildable_phids = $saved_query->getParameter('buildablePHIDs', array()); $all_phids = array_merge($container_phids, $buildable_phids); $revision_names = array(); $diff_names = array(); $repository_names = array(); $commit_names = array(); if ($all_phids) { $objects = id(new PhabricatorObjectQuery()) ->setViewer($this->requireViewer()) ->withPHIDs($all_phids) ->execute(); foreach ($all_phids as $phid) { $object = idx($objects, $phid); if (!$object) { continue; } if ($object instanceof DifferentialRevision) { $revision_names[] = 'D'.$object->getID(); } else if ($object instanceof DifferentialDiff) { $diff_names[] = $object->getID(); } else if ($object instanceof PhabricatorRepository) { $repository_names[] = 'r'.$object->getCallsign(); } else if ($object instanceof PhabricatorRepositoryCommit) { $repository = $object->getRepository(); $commit_names[] = $repository->formatCommitName( $object->getCommitIdentifier()); } } } $form ->appendChild( id(new AphrontFormTextControl()) ->setLabel(pht('Differential Revisions')) ->setName('revisions') ->setValue(implode(', ', $revision_names))) ->appendChild( id(new AphrontFormTextControl()) ->setLabel(pht('Differential Diffs')) ->setName('diffs') ->setValue(implode(', ', $diff_names))) ->appendChild( id(new AphrontFormTextControl()) ->setLabel(pht('Repositories')) ->setName('repositories') ->setValue(implode(', ', $repository_names))) ->appendChild( id(new AphrontFormTextControl()) ->setLabel(pht('Commits')) ->setName('commits') ->setValue(implode(', ', $commit_names))) ->appendChild( id(new AphrontFormSelectControl()) ->setLabel(pht('Origin')) ->setName('manual') ->setValue($this->getBoolFromQuery($saved_query, 'manual')) ->setOptions( array( '' => pht('(All Origins)'), 'true' => pht('Manual Buildables'), 'false' => pht('Automatic Buildables'), ))); } protected function getURI($path) { return '/harbormaster/'.$path; } public function getBuiltinQueryNames() { $names = array( 'all' => pht('All Buildables'), ); return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'all': return $query; } return parent::buildSavedQueryFromBuiltin($query_key); } protected function renderResultList( array $buildables, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($buildables, 'HarbormasterBuildable'); $viewer = $this->requireViewer(); $list = new PHUIObjectItemListView(); $list->setCards(true); foreach ($buildables as $buildable) { $id = $buildable->getID(); $item = id(new PHUIObjectItemView()) ->setHeader(pht('Buildable %d', $buildable->getID())); if ($buildable->getContainerHandle() !== null) { $item->addAttribute($buildable->getContainerHandle()->getName()); } if ($buildable->getBuildableHandle() !== null) { $item->addAttribute($buildable->getBuildableHandle()->getFullName()); } if ($id) { $item->setHref("/B{$id}"); } if ($buildable->getIsManualBuildable()) { - $item->addIcon('wrench-grey', pht('Manual')); + $item->addIcon('fa-wrench grey', pht('Manual')); } switch ($buildable->getBuildableStatus()) { case HarbormasterBuildable::STATUS_PASSED: $item->setBarColor('green'); $item->addByline(pht('Build Passed')); break; case HarbormasterBuildable::STATUS_FAILED: $item->setBarColor('red'); $item->addByline(pht('Build Failed')); break; case HarbormasterBuildable::STATUS_BUILDING: $item->setBarColor('red'); $item->addByline(pht('Building')); break; } $list->addItem($item); } return $list; } } diff --git a/src/applications/herald/controller/HeraldRuleViewController.php b/src/applications/herald/controller/HeraldRuleViewController.php index cea388ad3e..78c61194d1 100644 --- a/src/applications/herald/controller/HeraldRuleViewController.php +++ b/src/applications/herald/controller/HeraldRuleViewController.php @@ -1,189 +1,189 @@ <?php final class HeraldRuleViewController extends HeraldController { private $id; public function willProcessRequest(array $data) { $this->id = $data['id']; } public function processRequest() { $request = $this->getRequest(); $viewer = $request->getUser(); $rule = id(new HeraldRuleQuery()) ->setViewer($viewer) ->withIDs(array($this->id)) ->needConditionsAndActions(true) ->executeOne(); if (!$rule) { return new Aphront404Response(); } $header = id(new PHUIHeaderView()) ->setUser($viewer) ->setHeader($rule->getName()) ->setPolicyObject($rule); if ($rule->getIsDisabled()) { $header->setStatus( - 'oh-open', - 'red', + 'fa-ban', + 'dark', pht('Disabled')); } else { $header->setStatus( - 'oh-open', - null, + 'fa-check', + 'bluegrey', pht('Active')); } $actions = $this->buildActionView($rule); $properties = $this->buildPropertyView($rule, $actions); $id = $rule->getID(); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb("H{$id}"); $crumbs->setActionList($actions); $object_box = id(new PHUIObjectBoxView()) ->setHeader($header) ->addPropertyList($properties); $timeline = $this->buildTimeline($rule); return $this->buildApplicationPage( array( $crumbs, $object_box, $timeline, ), array( 'title' => $rule->getName(), 'device' => true, )); } private function buildActionView(HeraldRule $rule) { $viewer = $this->getRequest()->getUser(); $id = $rule->getID(); $view = id(new PhabricatorActionListView()) ->setUser($viewer) ->setObject($rule) ->setObjectURI($this->getApplicationURI("rule/{$id}/")); $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, $rule, PhabricatorPolicyCapability::CAN_EDIT); $view->addAction( id(new PhabricatorActionView()) ->setName(pht('Edit Rule')) ->setHref($this->getApplicationURI("edit/{$id}/")) ->setIcon('fa-pencil') ->setDisabled(!$can_edit) ->setWorkflow(!$can_edit)); if ($rule->getIsDisabled()) { $disable_uri = "disable/{$id}/enable/"; $disable_icon = 'fa-check-circle-o'; $disable_name = pht('Enable Rule'); } else { $disable_uri = "disable/{$id}/disable/"; $disable_icon = 'fa-ban'; $disable_name = pht('Disable Rule'); } $view->addAction( id(new PhabricatorActionView()) ->setName(pht('Disable Rule')) ->setHref($this->getApplicationURI($disable_uri)) ->setIcon($disable_icon) ->setName($disable_name) ->setDisabled(!$can_edit) ->setWorkflow(true)); return $view; } private function buildPropertyView( HeraldRule $rule, PhabricatorActionListView $actions) { $viewer = $this->getRequest()->getUser(); $this->loadHandles(HeraldAdapter::getHandlePHIDs($rule)); $view = id(new PHUIPropertyListView()) ->setUser($viewer) ->setObject($rule) ->setActionList($actions); $view->addProperty( pht('Rule Type'), idx(HeraldRuleTypeConfig::getRuleTypeMap(), $rule->getRuleType())); if ($rule->isPersonalRule()) { $view->addProperty( pht('Author'), $this->getHandle($rule->getAuthorPHID())->renderLink()); } $adapter = HeraldAdapter::getAdapterForContentType($rule->getContentType()); if ($adapter) { $view->addProperty( pht('Applies To'), idx( HeraldAdapter::getEnabledAdapterMap($viewer), $rule->getContentType())); if ($rule->isObjectRule()) { $view->addProperty( pht('Trigger Object'), $this->getHandle($rule->getTriggerObjectPHID())->renderLink()); } $view->invokeWillRenderEvent(); $view->addSectionHeader( pht('Rule Description'), PHUIPropertyListView::ICON_SUMMARY); $view->addTextContent( $adapter->renderRuleAsText($rule, $this->getLoadedHandles())); } return $view; } private function buildTimeline(HeraldRule $rule) { $viewer = $this->getRequest()->getUser(); $xactions = id(new HeraldTransactionQuery()) ->setViewer($viewer) ->withObjectPHIDs(array($rule->getPHID())) ->needComments(true) ->execute(); $engine = id(new PhabricatorMarkupEngine()) ->setViewer($viewer); foreach ($xactions as $xaction) { if ($xaction->getComment()) { $engine->addObject( $xaction->getComment(), PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT); } } $engine->process(); return id(new PhabricatorApplicationTransactionView()) ->setUser($viewer) ->setObjectPHID($rule->getPHID()) ->setTransactions($xactions) ->setMarkupEngine($engine); } } diff --git a/src/applications/maniphest/constants/ManiphestTaskStatus.php b/src/applications/maniphest/constants/ManiphestTaskStatus.php index f7b552cdfc..d3a75050ac 100644 --- a/src/applications/maniphest/constants/ManiphestTaskStatus.php +++ b/src/applications/maniphest/constants/ManiphestTaskStatus.php @@ -1,313 +1,312 @@ <?php /** * @task validate Configuration Validation */ final class ManiphestTaskStatus extends ManiphestConstants { const STATUS_OPEN = 'open'; const STATUS_CLOSED_RESOLVED = 'resolved'; const STATUS_CLOSED_WONTFIX = 'wontfix'; const STATUS_CLOSED_INVALID = 'invalid'; const STATUS_CLOSED_DUPLICATE = 'duplicate'; const STATUS_CLOSED_SPITE = 'spite'; const SPECIAL_DEFAULT = 'default'; const SPECIAL_CLOSED = 'closed'; const SPECIAL_DUPLICATE = 'duplicate'; private static function getStatusConfig() { return PhabricatorEnv::getEnvConfig('maniphest.statuses'); } private static function getEnabledStatusMap() { $spec = self::getStatusConfig(); $is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business'); foreach ($spec as $const => $status) { if ($is_serious && !empty($status['silly'])) { unset($spec[$const]); continue; } } return $spec; } public static function getTaskStatusMap() { return ipull(self::getEnabledStatusMap(), 'name'); } public static function getTaskStatusName($status) { return self::getStatusAttribute($status, 'name', pht('Unknown Status')); } public static function getTaskStatusFullName($status) { $name = self::getStatusAttribute($status, 'name.full'); if ($name !== null) { return $name; } return self::getStatusAttribute($status, 'name', pht('Unknown Status')); } public static function renderFullDescription($status) { if (self::isOpenStatus($status)) { $color = 'status'; - $icon = 'oh-open'; + $icon = 'fa-square-o bluegrey'; } else { $color = 'status-dark'; - $icon = 'oh-closed-dark'; + $icon = 'fa-check-square-o'; } $img = id(new PHUIIconView()) - ->setSpriteSheet(PHUIIconView::SPRITE_STATUS) - ->setSpriteIcon($icon); + ->setIconFont($icon); $tag = phutil_tag( 'span', array( 'class' => 'phui-header-'.$color.' plr', ), array( $img, self::getTaskStatusFullName($status), )); return $tag; } private static function getSpecialStatus($special) { foreach (self::getStatusConfig() as $const => $status) { if (idx($status, 'special') == $special) { return $const; } } return null; } public static function getDefaultStatus() { return self::getSpecialStatus(self::SPECIAL_DEFAULT); } public static function getDefaultClosedStatus() { return self::getSpecialStatus(self::SPECIAL_CLOSED); } public static function getDuplicateStatus() { return self::getSpecialStatus(self::SPECIAL_DUPLICATE); } public static function getOpenStatusConstants() { $result = array(); foreach (self::getEnabledStatusMap() as $const => $status) { if (empty($status['closed'])) { $result[] = $const; } } return $result; } public static function getClosedStatusConstants() { $all = array_keys(self::getTaskStatusMap()); $open = self::getOpenStatusConstants(); return array_diff($all, $open); } public static function isOpenStatus($status) { foreach (self::getOpenStatusConstants() as $constant) { if ($status == $constant) { return true; } } return false; } public static function isClosedStatus($status) { return !self::isOpenStatus($status); } public static function getStatusActionName($status) { return self::getStatusAttribute($status, 'name.action'); } public static function getStatusColor($status) { return self::getStatusAttribute($status, 'transaction.color'); } public static function getStatusIcon($status) { return self::getStatusAttribute($status, 'transaction.icon'); } public static function getStatusPrefixMap() { $map = array(); foreach (self::getEnabledStatusMap() as $const => $status) { foreach (idx($status, 'prefixes', array()) as $prefix) { $map[$prefix] = $const; } } $map += array( 'ref' => null, 'refs' => null, 'references' => null, 'cf.' => null, ); return $map; } public static function getStatusSuffixMap() { $map = array(); foreach (self::getEnabledStatusMap() as $const => $status) { foreach (idx($status, 'suffixes', array()) as $prefix) { $map[$prefix] = $const; } } return $map; } private static function getStatusAttribute($status, $key, $default = null) { $config = self::getStatusConfig(); $spec = idx($config, $status); if ($spec) { return idx($spec, $key, $default); } return $default; } /* -( Configuration Validation )------------------------------------------- */ /** * @task validate */ public static function isValidStatusConstant($constant) { if (strlen($constant) > 12) { return false; } if (!preg_match('/^[a-z0-9]+\z/', $constant)) { return false; } return true; } /** * @task validate */ public static function validateConfiguration(array $config) { foreach ($config as $key => $value) { if (!self::isValidStatusConstant($key)) { throw new Exception( pht( 'Key "%s" is not a valid status constant. Status constants must '. 'be 1-12 characters long and contain only lowercase letters (a-z) '. 'and digits (0-9). For example, "%s" or "%s" are reasonable '. 'choices.', $key, 'open', 'closed')); } if (!is_array($value)) { throw new Exception( pht( 'Value for key "%s" should be a dictionary.', $key)); } PhutilTypeSpec::checkMap( $value, array( 'name' => 'string', 'name.full' => 'optional string', 'name.action' => 'optional string', 'closed' => 'optional bool', 'special' => 'optional string', 'transaction.icon' => 'optional string', 'transaction.color' => 'optional string', 'silly' => 'optional bool', 'prefixes' => 'optional list<string>', 'suffixes' => 'optional list<string>', )); } $special_map = array(); foreach ($config as $key => $value) { $special = idx($value, 'special'); if (!$special) { continue; } if (isset($special_map[$special])) { throw new Exception( pht( 'Configuration has two statuses both marked with the special '. 'attribute "%s" ("%s" and "%s"). There should be only one.', $special, $special_map[$special], $key)); } switch ($special) { case self::SPECIAL_DEFAULT: if (!empty($value['closed'])) { throw new Exception( pht( 'Status "%s" is marked as default, but it is a closed '. 'status. The default status should be an open status.', $key)); } break; case self::SPECIAL_CLOSED: if (empty($value['closed'])) { throw new Exception( pht( 'Status "%s" is marked as the default status for closing '. 'tasks, but is not a closed status. It should be a closed '. 'status.', $key)); } break; case self::SPECIAL_DUPLICATE: if (empty($value['closed'])) { throw new Exception( pht( 'Status "%s" is marked as the status for closing tasks as '. 'duplicates, but it is not a closed status. It should '. 'be a closed status.', $key)); } break; } $special_map[$special] = $key; } // NOTE: We're not explicitly validating that we have at least one open // and one closed status, because the DEFAULT and CLOSED specials imply // that to be true. If those change in the future, that might become a // reasonable thing to validate. $required = array( self::SPECIAL_DEFAULT, self::SPECIAL_CLOSED, self::SPECIAL_DUPLICATE, ); foreach ($required as $required_special) { if (!isset($special_map[$required_special])) { throw new Exception( pht( 'Configuration defines no task status with special attribute '. '"%s", but you must specify a status which fills this special '. 'role.', $required_special)); } } } } diff --git a/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php b/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php index a932a839af..b2cc713181 100644 --- a/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php +++ b/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php @@ -1,153 +1,153 @@ <?php final class PhabricatorApplicationDetailViewController extends PhabricatorApplicationsController{ private $application; public function willProcessRequest(array $data) { $this->application = $data['application']; } public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); $selected = id(new PhabricatorApplicationQuery()) ->setViewer($user) ->withClasses(array($this->application)) ->executeOne(); if (!$selected) { return new Aphront404Response(); } $title = $selected->getName(); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb($selected->getName()); $header = id(new PHUIHeaderView()) ->setHeader($title) ->setUser($user) ->setPolicyObject($selected); if ($selected->isInstalled()) { - $header->setStatus('oh-ok', null, pht('Installed')); + $header->setStatus('fa-check', 'bluegrey', pht('Installed')); } else { - $header->setStatus('policy-noone', null, pht('Uninstalled')); + $header->setStatus('fa-ban', 'dark', pht('Uninstalled')); } $actions = $this->buildActionView($user, $selected); $properties = $this->buildPropertyView($selected, $actions); $object_box = id(new PHUIObjectBoxView()) ->setHeader($header) ->addPropertyList($properties); return $this->buildApplicationPage( array( $crumbs, $object_box, ), array( 'title' => $title, 'device' => true, )); } private function buildPropertyView( PhabricatorApplication $application, PhabricatorActionListView $actions) { $viewer = $this->getRequest()->getUser(); $properties = id(new PHUIPropertyListView()) ->addProperty(pht('Description'), $application->getShortDescription()); $properties->setActionList($actions); if ($application->isBeta()) { $properties->addProperty( pht('Release'), pht('Beta')); } $descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions( $viewer, $application); $properties->addSectionHeader(pht('Policies')); foreach ($application->getCapabilities() as $capability) { $properties->addProperty( $application->getCapabilityLabel($capability), idx($descriptions, $capability)); } return $properties; } private function buildActionView( PhabricatorUser $user, PhabricatorApplication $selected) { $view = id(new PhabricatorActionListView()) ->setUser($user) ->setObjectURI($this->getRequest()->getRequestURI()); $can_edit = PhabricatorPolicyFilter::hasCapability( $user, $selected, PhabricatorPolicyCapability::CAN_EDIT); $edit_uri = $this->getApplicationURI('edit/'.get_class($selected).'/'); $view->addAction( id(new PhabricatorActionView()) ->setName(pht('Edit Policies')) ->setIcon('fa-pencil') ->setDisabled(!$can_edit) ->setWorkflow(!$can_edit) ->setHref($edit_uri)); if ($selected->canUninstall()) { if ($selected->isInstalled()) { $view->addAction( id(new PhabricatorActionView()) ->setName(pht('Uninstall')) ->setIcon('fa-times') ->setDisabled(!$can_edit) ->setWorkflow(true) ->setHref( $this->getApplicationURI(get_class($selected).'/uninstall/'))); } else { $action = id(new PhabricatorActionView()) ->setName(pht('Install')) ->setIcon('fa-plus') ->setDisabled(!$can_edit) ->setWorkflow(true) ->setHref( $this->getApplicationURI(get_class($selected).'/install/')); $beta_enabled = PhabricatorEnv::getEnvConfig( 'phabricator.show-beta-applications'); if ($selected->isBeta() && !$beta_enabled) { $action->setDisabled(true); } $view->addAction($action); } } else { $view->addAction( id(new PhabricatorActionView()) ->setName(pht('Uninstall')) ->setIcon('fa-times') ->setWorkflow(true) ->setDisabled(true) ->setHref( $this->getApplicationURI(get_class($selected).'/uninstall/'))); } return $view; } } diff --git a/src/applications/passphrase/controller/PassphraseCredentialViewController.php b/src/applications/passphrase/controller/PassphraseCredentialViewController.php index bab9e17629..3c5a836761 100644 --- a/src/applications/passphrase/controller/PassphraseCredentialViewController.php +++ b/src/applications/passphrase/controller/PassphraseCredentialViewController.php @@ -1,208 +1,208 @@ <?php final class PassphraseCredentialViewController extends PassphraseController { private $id; public function willProcessRequest(array $data) { $this->id = $data['id']; } public function processRequest() { $request = $this->getRequest(); $viewer = $request->getUser(); $credential = id(new PassphraseCredentialQuery()) ->setViewer($viewer) ->withIDs(array($this->id)) ->executeOne(); if (!$credential) { return new Aphront404Response(); } $type = PassphraseCredentialType::getTypeByConstant( $credential->getCredentialType()); if (!$type) { throw new Exception(pht('Credential has invalid type "%s"!', $type)); } $xactions = id(new PassphraseCredentialTransactionQuery()) ->setViewer($viewer) ->withObjectPHIDs(array($credential->getPHID())) ->execute(); $engine = id(new PhabricatorMarkupEngine()) ->setViewer($viewer); $timeline = id(new PhabricatorApplicationTransactionView()) ->setUser($viewer) ->setObjectPHID($credential->getPHID()) ->setTransactions($xactions); $title = pht('%s %s', 'K'.$credential->getID(), $credential->getName()); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb('K'.$credential->getID()); $header = $this->buildHeaderView($credential); $actions = $this->buildActionView($credential, $type); $properties = $this->buildPropertyView($credential, $type, $actions); $box = id(new PHUIObjectBoxView()) ->setHeader($header) ->addPropertyList($properties); return $this->buildApplicationPage( array( $crumbs, $box, $timeline, ), array( 'title' => $title, 'device' => true, )); } private function buildHeaderView(PassphraseCredential $credential) { $viewer = $this->getRequest()->getUser(); $header = id(new PHUIHeaderView()) ->setUser($viewer) ->setHeader($credential->getName()) ->setPolicyObject($credential); if ($credential->getIsDestroyed()) { - $header->setStatus('reject', 'red', pht('Destroyed')); + $header->setStatus('fa-ban', 'red', pht('Destroyed')); } return $header; } private function buildActionView( PassphraseCredential $credential, PassphraseCredentialType $type) { $viewer = $this->getRequest()->getUser(); $id = $credential->getID(); $is_locked = $credential->getIsLocked(); if ($is_locked) { $credential_lock_text = pht('Locked Permanently'); $credential_lock_icon = 'fa-lock'; } else { $credential_lock_text = pht('Lock Permanently'); $credential_lock_icon = 'fa-unlock'; } $actions = id(new PhabricatorActionListView()) ->setObjectURI('/K'.$id) ->setUser($viewer); $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, $credential, PhabricatorPolicyCapability::CAN_EDIT); $actions->addAction( id(new PhabricatorActionView()) ->setName(pht('Edit Credential')) ->setIcon('fa-pencil') ->setHref($this->getApplicationURI("edit/{$id}/")) ->setDisabled(!$can_edit) ->setWorkflow(!$can_edit)); if (!$credential->getIsDestroyed()) { $actions->addAction( id(new PhabricatorActionView()) ->setName(pht('Destroy Credential')) ->setIcon('fa-times') ->setHref($this->getApplicationURI("destroy/{$id}/")) ->setDisabled(!$can_edit) ->setWorkflow(true)); $actions->addAction( id(new PhabricatorActionView()) ->setName(pht('Show Secret')) ->setIcon('fa-eye') ->setHref($this->getApplicationURI("reveal/{$id}/")) ->setDisabled(!$can_edit || $is_locked) ->setWorkflow(true)); if ($type->hasPublicKey()) { $actions->addAction( id(new PhabricatorActionView()) ->setName(pht('Show Public Key')) ->setIcon('fa-download') ->setHref($this->getApplicationURI("public/{$id}/")) ->setWorkflow(true) ->setDisabled($is_locked)); } $actions->addAction( id(new PhabricatorActionView()) ->setName($credential_lock_text) ->setIcon($credential_lock_icon) ->setHref($this->getApplicationURI("lock/{$id}/")) ->setDisabled($is_locked) ->setWorkflow(true)); } return $actions; } private function buildPropertyView( PassphraseCredential $credential, PassphraseCredentialType $type, PhabricatorActionListView $actions) { $viewer = $this->getRequest()->getUser(); $properties = id(new PHUIPropertyListView()) ->setUser($viewer) ->setObject($credential) ->setActionList($actions); $properties->addProperty( pht('Credential Type'), $type->getCredentialTypeName()); $descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions( $viewer, $credential); $properties->addProperty( pht('Editable By'), $descriptions[PhabricatorPolicyCapability::CAN_EDIT]); $properties->addProperty( pht('Username'), $credential->getUsername()); $used_by_phids = PhabricatorEdgeQuery::loadDestinationPHIDs( $credential->getPHID(), PhabricatorEdgeConfig::TYPE_CREDENTIAL_USED_BY_OBJECT); if ($used_by_phids) { $this->loadHandles($used_by_phids); $properties->addProperty( pht('Used By'), $this->renderHandlesForPHIDs($used_by_phids)); } $description = $credential->getDescription(); if (strlen($description)) { $properties->addSectionHeader( pht('Description'), PHUIPropertyListView::ICON_SUMMARY); $properties->addTextContent( PhabricatorMarkupEngine::renderOneObject( id(new PhabricatorMarkupOneOff()) ->setContent($description), 'default', $viewer)); } return $properties; } } diff --git a/src/applications/passphrase/query/PassphraseCredentialSearchEngine.php b/src/applications/passphrase/query/PassphraseCredentialSearchEngine.php index e4e99790ca..6028547b50 100644 --- a/src/applications/passphrase/query/PassphraseCredentialSearchEngine.php +++ b/src/applications/passphrase/query/PassphraseCredentialSearchEngine.php @@ -1,116 +1,116 @@ <?php final class PassphraseCredentialSearchEngine extends PhabricatorApplicationSearchEngine { public function getApplicationClassName() { return 'PhabricatorApplicationPassphrase'; } public function buildSavedQueryFromRequest(AphrontRequest $request) { $saved = new PhabricatorSavedQuery(); $saved->setParameter( 'isDestroyed', $this->readBoolFromRequest($request, 'isDestroyed')); return $saved; } public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { $query = id(new PassphraseCredentialQuery()); $destroyed = $saved->getParameter('isDestroyed'); if ($destroyed !== null) { $query->withIsDestroyed($destroyed); } return $query; } public function buildSearchForm( AphrontFormView $form, PhabricatorSavedQuery $saved_query) { $form->appendChild( id(new AphrontFormSelectControl()) ->setName('isDestroyed') ->setLabel(pht('Status')) ->setValue($this->getBoolFromQuery($saved_query, 'isDestroyed')) ->setOptions( array( '' => pht('Show All Credentials'), 'false' => pht('Show Only Active Credentials'), 'true' => pht('Show Only Destroyed Credentials'), ))); } protected function getURI($path) { return '/passphrase/'.$path; } public function getBuiltinQueryNames() { $names = array( 'active' => pht('Active Credentials'), 'all' => pht('All Credentials'), ); return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'all': return $query; case 'active': return $query->setParameter('isDestroyed', false); } return parent::buildSavedQueryFromBuiltin($query_key); } protected function renderResultList( array $credentials, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($credentials, 'PassphraseCredential'); $viewer = $this->requireViewer(); $list = new PHUIObjectItemListView(); $list->setUser($viewer); foreach ($credentials as $credential) { $item = id(new PHUIObjectItemView()) ->setObjectName('K'.$credential->getID()) ->setHeader($credential->getName()) ->setHref('/K'.$credential->getID()) ->setObject($credential); $item->addAttribute( pht('Login: %s', $credential->getUsername())); if ($credential->getIsDestroyed()) { - $item->addIcon('disable', pht('Destroyed')); + $item->addIcon('fa-ban', pht('Destroyed')); $item->setDisabled(true); } $type = PassphraseCredentialType::getTypeByConstant( $credential->getCredentialType()); if ($type) { - $item->addIcon('wrench', $type->getCredentialTypeName()); + $item->addIcon('fa-wrench', $type->getCredentialTypeName()); } $list->addItem($item); } return $list; } } diff --git a/src/applications/people/phid/PhabricatorPeoplePHIDTypeUser.php b/src/applications/people/phid/PhabricatorPeoplePHIDTypeUser.php index db6295006f..a4c344c326 100644 --- a/src/applications/people/phid/PhabricatorPeoplePHIDTypeUser.php +++ b/src/applications/people/phid/PhabricatorPeoplePHIDTypeUser.php @@ -1,90 +1,90 @@ <?php final class PhabricatorPeoplePHIDTypeUser extends PhabricatorPHIDType { const TYPECONST = 'USER'; public function getTypeConstant() { return self::TYPECONST; } public function getTypeName() { return pht('User'); } public function getPHIDTypeApplicationClass() { return 'PhabricatorApplicationPeople'; } public function getTypeIcon() { - return 'policy-all'; + return 'fa-user bluegrey'; } public function newObject() { return new PhabricatorUser(); } protected function buildQueryForObjects( PhabricatorObjectQuery $query, array $phids) { return id(new PhabricatorPeopleQuery()) ->withPHIDs($phids) ->needProfileImage(true) ->needStatus(true); } public function loadHandles( PhabricatorHandleQuery $query, array $handles, array $objects) { foreach ($handles as $phid => $handle) { $user = $objects[$phid]; $realname = $user->getRealName(); $handle->setName($user->getUsername()); $handle->setURI('/p/'.$user->getUsername().'/'); $handle->setFullName($user->getFullName()); $handle->setImageURI($user->loadProfileImageURI()); $handle->setDisabled(!$user->isUserActivated()); if ($user->hasStatus()) { $status = $user->getStatus(); $handle->setStatus($status->getTextStatus()); $handle->setTitle($status->getTerseSummary($query->getViewer())); } } } public function canLoadNamedObject($name) { return preg_match('/^@.+/', $name); } public function loadNamedObjects( PhabricatorObjectQuery $query, array $names) { $id_map = array(); foreach ($names as $name) { $id = substr($name, 1); $id_map[$id][] = $name; } $objects = id(new PhabricatorPeopleQuery()) ->setViewer($query->getViewer()) ->withUsernames(array_keys($id_map)) ->execute(); $results = array(); foreach ($objects as $id => $object) { $username = $object->getUsername(); foreach (idx($id_map, $username, array()) as $name) { $results[$name] = $object; } } return $results; } } diff --git a/src/applications/policy/storage/PhabricatorPolicy.php b/src/applications/policy/storage/PhabricatorPolicy.php index c32bb450a5..5240a64c80 100644 --- a/src/applications/policy/storage/PhabricatorPolicy.php +++ b/src/applications/policy/storage/PhabricatorPolicy.php @@ -1,355 +1,354 @@ <?php final class PhabricatorPolicy extends PhabricatorPolicyDAO implements PhabricatorPolicyInterface { const ACTION_ALLOW = 'allow'; const ACTION_DENY = 'deny'; private $name; private $shortName; private $type; private $href; private $workflow; private $icon; protected $rules = array(); protected $defaultAction = self::ACTION_DENY; private $ruleObjects = self::ATTACHABLE; public function getConfiguration() { return array( self::CONFIG_AUX_PHID => true, self::CONFIG_SERIALIZATION => array( 'rules' => self::SERIALIZATION_JSON, ), ) + parent::getConfiguration(); } public function generatePHID() { return PhabricatorPHID::generateNewPHID( PhabricatorPolicyPHIDTypePolicy::TYPECONST); } public static function newFromPolicyAndHandle( $policy_identifier, PhabricatorObjectHandle $handle = null) { $is_global = PhabricatorPolicyQuery::isGlobalPolicy($policy_identifier); if ($is_global) { return PhabricatorPolicyQuery::getGlobalPolicy($policy_identifier); } if (!$handle) { throw new Exception( "Policy identifier is an object PHID ('{$policy_identifier}'), but no ". "object handle was provided. A handle must be provided for object ". "policies."); } $handle_phid = $handle->getPHID(); if ($policy_identifier != $handle_phid) { throw new Exception( "Policy identifier is an object PHID ('{$policy_identifier}'), but ". "the provided handle has a different PHID ('{$handle_phid}'). The ". "handle must correspond to the policy identifier."); } $policy = id(new PhabricatorPolicy()) ->setPHID($policy_identifier) ->setHref($handle->getURI()); $phid_type = phid_get_type($policy_identifier); switch ($phid_type) { case PhabricatorProjectPHIDTypeProject::TYPECONST: $policy->setType(PhabricatorPolicyType::TYPE_PROJECT); $policy->setName($handle->getName()); break; case PhabricatorPeoplePHIDTypeUser::TYPECONST: $policy->setType(PhabricatorPolicyType::TYPE_USER); $policy->setName($handle->getFullName()); break; case PhabricatorPolicyPHIDTypePolicy::TYPECONST: // TODO: This creates a weird handle-based version of a rule policy. // It behaves correctly, but can't be applied since it doesn't have // any rules. It is used to render transactions, and might need some // cleanup. break; default: $policy->setType(PhabricatorPolicyType::TYPE_MASKED); $policy->setName($handle->getFullName()); break; } $policy->makeEphemeral(); return $policy; } public function setType($type) { $this->type = $type; return $this; } public function getType() { if (!$this->type) { return PhabricatorPolicyType::TYPE_CUSTOM; } return $this->type; } public function setName($name) { $this->name = $name; return $this; } public function getName() { if (!$this->name) { return pht('Custom Policy'); } return $this->name; } public function setShortName($short_name) { $this->shortName = $short_name; return $this; } public function getShortName() { if ($this->shortName) { return $this->shortName; } return $this->getName(); } public function setHref($href) { $this->href = $href; return $this; } public function getHref() { return $this->href; } public function setWorkflow($workflow) { $this->workflow = $workflow; return $this; } public function getWorkflow() { return $this->workflow; } public function getIcon() { switch ($this->getType()) { case PhabricatorPolicyType::TYPE_GLOBAL: static $map = array( - PhabricatorPolicies::POLICY_PUBLIC => 'policy-public', - PhabricatorPolicies::POLICY_USER => 'policy-all', - PhabricatorPolicies::POLICY_ADMIN => 'policy-admin', - PhabricatorPolicies::POLICY_NOONE => 'policy-noone', + PhabricatorPolicies::POLICY_PUBLIC => 'fa-globe', + PhabricatorPolicies::POLICY_USER => 'fa-users', + PhabricatorPolicies::POLICY_ADMIN => 'fa-eye', + PhabricatorPolicies::POLICY_NOONE => 'fa-ban', ); - return idx($map, $this->getPHID(), 'policy-unknown'); + return idx($map, $this->getPHID(), 'fa-question-circle'); case PhabricatorPolicyType::TYPE_USER: - return 'policy-user'; + return 'fa-user'; case PhabricatorPolicyType::TYPE_PROJECT: - return 'policy-project'; + return 'fa-briefcase'; case PhabricatorPolicyType::TYPE_CUSTOM: case PhabricatorPolicyType::TYPE_MASKED: - return 'policy-custom'; + return 'fa-certificate'; default: - return 'policy-unknown'; + return 'fa-question-circle'; } } public function getSortKey() { return sprintf( '%02d%s', PhabricatorPolicyType::getPolicyTypeOrder($this->getType()), $this->getSortName()); } private function getSortName() { if ($this->getType() == PhabricatorPolicyType::TYPE_GLOBAL) { static $map = array( PhabricatorPolicies::POLICY_PUBLIC => 0, PhabricatorPolicies::POLICY_USER => 1, PhabricatorPolicies::POLICY_ADMIN => 2, PhabricatorPolicies::POLICY_NOONE => 3, ); return idx($map, $this->getPHID()); } return $this->getName(); } public static function getPolicyExplanation( PhabricatorUser $viewer, $policy) { switch ($policy) { case PhabricatorPolicies::POLICY_PUBLIC: return pht('This object is public.'); case PhabricatorPolicies::POLICY_USER: return pht('Logged in users can take this action.'); case PhabricatorPolicies::POLICY_ADMIN: return pht('Administrators can take this action.'); case PhabricatorPolicies::POLICY_NOONE: return pht('By default, no one can take this action.'); default: $handle = id(new PhabricatorHandleQuery()) ->setViewer($viewer) ->withPHIDs(array($policy)) ->executeOne(); $type = phid_get_type($policy); if ($type == PhabricatorProjectPHIDTypeProject::TYPECONST) { return pht( 'Members of the project "%s" can take this action.', $handle->getFullName()); } else if ($type == PhabricatorPeoplePHIDTypeUser::TYPECONST) { return pht( '%s can take this action.', $handle->getFullName()); } else if ($type == PhabricatorPolicyPHIDTypePolicy::TYPECONST) { return pht( 'This object has a custom policy controlling who can take this '. 'action.'); } else { return pht( 'This object has an unknown or invalid policy setting ("%s").', $policy); } } } public function getFullName() { switch ($this->getType()) { case PhabricatorPolicyType::TYPE_PROJECT: return pht('Project: %s', $this->getName()); case PhabricatorPolicyType::TYPE_MASKED: return pht('Other: %s', $this->getName()); default: return $this->getName(); } } public function renderDescription($icon=false) { $img = null; if ($icon) { $img = id(new PHUIIconView()) - ->setSpriteSheet(PHUIIconView::SPRITE_STATUS) - ->setSpriteIcon($this->getIcon()); + ->setIconFont($this->getIcon()); } if ($this->getHref()) { $desc = javelin_tag( 'a', array( 'href' => $this->getHref(), 'class' => 'policy-link', 'sigil' => $this->getWorkflow() ? 'workflow' : null, ), array( $img, $this->getName(), )); } else { if ($img) { $desc = array($img, $this->getName()); } else { $desc = $this->getName(); } } switch ($this->getType()) { case PhabricatorPolicyType::TYPE_PROJECT: return pht('%s (Project)', $desc); case PhabricatorPolicyType::TYPE_CUSTOM: return $desc; case PhabricatorPolicyType::TYPE_MASKED: return pht( '%s (You do not have permission to view policy details.)', $desc); default: return $desc; } } /** * Return a list of custom rule classes (concrete subclasses of * @{class:PhabricatorPolicyRule}) this policy uses. * * @return list<string> List of class names. */ public function getCustomRuleClasses() { $classes = array(); foreach ($this->getRules() as $rule) { $class = idx($rule, 'rule'); try { if (class_exists($class)) { $classes[$class] = $class; } } catch (Exception $ex) { continue; } } return array_keys($classes); } /** * Return a list of all values used by a given rule class to implement this * policy. This is used to bulk load data (like project memberships) in order * to apply policy filters efficiently. * * @param string Policy rule classname. * @return list<wild> List of values used in this policy. */ public function getCustomRuleValues($rule_class) { $values = array(); foreach ($this->getRules() as $rule) { if ($rule['rule'] == $rule_class) { $values[] = $rule['value']; } } return $values; } public function attachRuleObjects(array $objects) { $this->ruleObjects = $objects; return $this; } public function getRuleObjects() { return $this->assertAttached($this->ruleObjects); } /* -( PhabricatorPolicyInterface )----------------------------------------- */ public function getCapabilities() { return array( PhabricatorPolicyCapability::CAN_VIEW, ); } public function getPolicy($capability) { // NOTE: We implement policies only so we can comply with the interface. // The actual query skips them, as enforcing policies on policies seems // perilous and isn't currently required by the application. return PhabricatorPolicies::POLICY_PUBLIC; } public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { return false; } public function describeAutomaticCapability($capability) { return null; } } diff --git a/src/applications/project/controller/PhabricatorProjectColumnDetailController.php b/src/applications/project/controller/PhabricatorProjectColumnDetailController.php index 36b15e130e..7277f114d8 100644 --- a/src/applications/project/controller/PhabricatorProjectColumnDetailController.php +++ b/src/applications/project/controller/PhabricatorProjectColumnDetailController.php @@ -1,165 +1,165 @@ <?php final class PhabricatorProjectColumnDetailController extends PhabricatorProjectBoardController { private $id; private $projectID; public function willProcessRequest(array $data) { $this->projectID = $data['projectID']; $this->id = idx($data, 'id'); } public function processRequest() { $request = $this->getRequest(); $viewer = $request->getUser(); $project = id(new PhabricatorProjectQuery()) ->setViewer($viewer) ->requireCapabilities( array( PhabricatorPolicyCapability::CAN_VIEW, )) ->withIDs(array($this->projectID)) ->executeOne(); if (!$project) { return new Aphront404Response(); } $this->setProject($project); $column = id(new PhabricatorProjectColumnQuery()) ->setViewer($viewer) ->withIDs(array($this->id)) ->requireCapabilities( array( PhabricatorPolicyCapability::CAN_VIEW, )) ->executeOne(); if (!$column) { return new Aphront404Response(); } $xactions = id(new PhabricatorProjectColumnTransactionQuery()) ->setViewer($viewer) ->withObjectPHIDs(array($column->getPHID())) ->execute(); $engine = id(new PhabricatorMarkupEngine()) ->setViewer($viewer); $timeline = id(new PhabricatorApplicationTransactionView()) ->setUser($viewer) ->setObjectPHID($column->getPHID()) ->setTransactions($xactions); $title = pht('%s', $column->getName()); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb( pht('Board'), $this->getApplicationURI('board/'.$project->getID().'/')); $crumbs->addTextCrumb($title); $header = $this->buildHeaderView($column); $actions = $this->buildActionView($column); $properties = $this->buildPropertyView($column, $actions); $box = id(new PHUIObjectBoxView()) ->setHeader($header) ->addPropertyList($properties); return $this->buildApplicationPage( array( $crumbs, $box, $timeline, ), array( 'title' => $title, 'device' => true, )); } private function buildHeaderView(PhabricatorProjectColumn $column) { $viewer = $this->getRequest()->getUser(); $header = id(new PHUIHeaderView()) ->setUser($viewer) ->setHeader($column->getName()) ->setPolicyObject($column); if ($column->isDeleted()) { - $header->setStatus('reject', 'red', pht('Deleted')); + $header->setStatus('fa-ban', 'dark', pht('Deleted')); } return $header; } private function buildActionView(PhabricatorProjectColumn $column) { $viewer = $this->getRequest()->getUser(); $id = $column->getID(); $project_id = $this->getProject()->getID(); $base_uri = '/board/'.$project_id.'/'; $actions = id(new PhabricatorActionListView()) ->setObjectURI($this->getApplicationURI($base_uri.'column/'.$id.'/')) ->setUser($viewer); $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, $column, PhabricatorPolicyCapability::CAN_EDIT); $actions->addAction( id(new PhabricatorActionView()) ->setName(pht('Edit column')) ->setIcon('fa-pencil') ->setHref($this->getApplicationURI($base_uri.'edit/'.$id.'/')) ->setDisabled(!$can_edit) ->setWorkflow(!$can_edit)); if (!$column->isDeleted()) { $actions->addAction( id(new PhabricatorActionView()) ->setName(pht('Delete column')) ->setIcon('fa-times') ->setHref($this->getApplicationURI($base_uri.'delete/'.$id.'/')) ->setDisabled(!$can_edit) ->setWorkflow(true)); } else { $actions->addAction( id(new PhabricatorActionView()) ->setName(pht('Activate column')) ->setIcon('fa-play-circle-o') ->setHref($this->getApplicationURI($base_uri.'delete/'.$id.'/')) ->setDisabled(!$can_edit) ->setWorkflow(true)); } return $actions; } private function buildPropertyView( PhabricatorProjectColumn $column, PhabricatorActionListView $actions) { $viewer = $this->getRequest()->getUser(); $properties = id(new PHUIPropertyListView()) ->setUser($viewer) ->setObject($column) ->setActionList($actions); $descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions( $viewer, $column); $properties->addProperty( pht('Editable By'), $descriptions[PhabricatorPolicyCapability::CAN_EDIT]); return $properties; } } diff --git a/src/applications/project/controller/PhabricatorProjectEditMainController.php b/src/applications/project/controller/PhabricatorProjectEditMainController.php index e0d6848f5c..948bb1bc2f 100644 --- a/src/applications/project/controller/PhabricatorProjectEditMainController.php +++ b/src/applications/project/controller/PhabricatorProjectEditMainController.php @@ -1,157 +1,157 @@ <?php final class PhabricatorProjectEditMainController extends PhabricatorProjectController { private $id; public function willProcessRequest(array $data) { $this->id = idx($data, 'id'); } public function processRequest() { $request = $this->getRequest(); $viewer = $request->getUser(); $project = id(new PhabricatorProjectQuery()) ->setViewer($viewer) ->withIDs(array($this->id)) ->needImages(true) ->executeOne(); if (!$project) { return new Aphront404Response(); } $header = id(new PHUIHeaderView()) ->setHeader(pht('Edit %s', $project->getName())) ->setUser($viewer) ->setPolicyObject($project) ->setImage($project->getProfileImageURI()); if ($project->getStatus() == PhabricatorProjectStatus::STATUS_ACTIVE) { - $header->setStatus('oh-ok', '', pht('Active')); + $header->setStatus('fa-check', 'bluegrey', pht('Active')); } else { - $header->setStatus('policy-noone', '', pht('Archived')); + $header->setStatus('fa-ban', 'dark', pht('Archived')); } $actions = $this->buildActionListView($project); $properties = $this->buildPropertyListView($project, $actions); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb( $project->getName(), $this->getApplicationURI('view/'.$project->getID().'/')); $crumbs->addTextCrumb(pht('Edit')); $crumbs->setActionList($actions); $object_box = id(new PHUIObjectBoxView()) ->setHeader($header) ->addPropertyList($properties); $xactions = id(new PhabricatorProjectTransactionQuery()) ->setViewer($viewer) ->withObjectPHIDs(array($project->getPHID())) ->execute(); $timeline = id(new PhabricatorApplicationTransactionView()) ->setUser($viewer) ->setObjectPHID($project->getPHID()) ->setShouldTerminate(true) ->setTransactions($xactions); return $this->buildApplicationPage( array( $crumbs, $object_box, $timeline, ), array( 'title' => $project->getName(), 'device' => true, )); } private function buildActionListView(PhabricatorProject $project) { $request = $this->getRequest(); $viewer = $request->getUser(); $id = $project->getID(); $view = id(new PhabricatorActionListView()) ->setUser($viewer) ->setObjectURI($request->getRequestURI()); $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, $project, PhabricatorPolicyCapability::CAN_EDIT); $view->addAction( id(new PhabricatorActionView()) ->setName(pht('Edit Details')) ->setIcon('fa-pencil') ->setHref($this->getApplicationURI("details/{$id}/")) ->setDisabled(!$can_edit) ->setWorkflow(!$can_edit)); $view->addAction( id(new PhabricatorActionView()) ->setName(pht('Edit Picture')) ->setIcon('fa-picture-o') ->setHref($this->getApplicationURI("picture/{$id}/")) ->setDisabled(!$can_edit) ->setWorkflow(!$can_edit)); if ($project->isArchived()) { $view->addAction( id(new PhabricatorActionView()) ->setName(pht('Unarchive Project')) - ->setIcon('fa-circle-check') + ->setIcon('fa-check') ->setHref($this->getApplicationURI("archive/{$id}/")) ->setDisabled(!$can_edit) ->setWorkflow(true)); } else { $view->addAction( id(new PhabricatorActionView()) ->setName(pht('Archive Project')) ->setIcon('fa-ban') ->setHref($this->getApplicationURI("archive/{$id}/")) ->setDisabled(!$can_edit) ->setWorkflow(true)); } return $view; } private function buildPropertyListView( PhabricatorProject $project, PhabricatorActionListView $actions) { $request = $this->getRequest(); $viewer = $request->getUser(); $view = id(new PHUIPropertyListView()) ->setUser($viewer) ->setObject($project) ->setActionList($actions); $descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions( $viewer, $project); $view->addProperty( pht('Visible To'), $descriptions[PhabricatorPolicyCapability::CAN_VIEW]); $view->addProperty( pht('Editable By'), $descriptions[PhabricatorPolicyCapability::CAN_EDIT]); $view->addProperty( pht('Joinable By'), $descriptions[PhabricatorPolicyCapability::CAN_JOIN]); return $view; } } diff --git a/src/applications/project/controller/PhabricatorProjectProfileController.php b/src/applications/project/controller/PhabricatorProjectProfileController.php index 78f775a964..3586db683f 100644 --- a/src/applications/project/controller/PhabricatorProjectProfileController.php +++ b/src/applications/project/controller/PhabricatorProjectProfileController.php @@ -1,265 +1,265 @@ <?php final class PhabricatorProjectProfileController extends PhabricatorProjectController { private $id; public function shouldAllowPublic() { return true; } public function willProcessRequest(array $data) { $this->id = idx($data, 'id'); } public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); $project = id(new PhabricatorProjectQuery()) ->setViewer($user) ->withIDs(array($this->id)) ->needMembers(true) ->needImages(true) ->executeOne(); if (!$project) { return new Aphront404Response(); } $picture = $project->getProfileImageURI(); require_celerity_resource('phabricator-profile-css'); $tasks = $this->renderTasksPage($project); $query = new PhabricatorFeedQuery(); $query->setFilterPHIDs( array( $project->getPHID(), )); $query->setLimit(50); $query->setViewer($this->getRequest()->getUser()); $stories = $query->execute(); $feed = $this->renderStories($stories); $content = phutil_tag_div( 'phabricator-project-layout', array($tasks, $feed)); $id = $this->id; $icon = id(new PHUIIconView()) ->setIconFont('fa-columns'); $board_btn = id(new PHUIButtonView()) ->setTag('a') ->setText(pht('Workboards')) ->setHref($this->getApplicationURI("board/{$id}/")) ->setIcon($icon); $header = id(new PHUIHeaderView()) ->setHeader($project->getName()) ->setUser($user) ->setPolicyObject($project) ->setImage($picture) ->addActionLink($board_btn); if ($project->getStatus() == PhabricatorProjectStatus::STATUS_ACTIVE) { - $header->setStatus('oh-ok', '', pht('Active')); + $header->setStatus('fa-check', 'bluegrey', pht('Active')); } else { - $header->setStatus('policy-noone', '', pht('Archived')); + $header->setStatus('fa-ban', 'dark', pht('Archived')); } $actions = $this->buildActionListView($project); $properties = $this->buildPropertyListView($project, $actions); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb($project->getName()) ->setActionList($actions); $object_box = id(new PHUIObjectBoxView()) ->setHeader($header) ->addPropertyList($properties); return $this->buildApplicationPage( array( $crumbs, $object_box, $content, ), array( 'title' => $project->getName(), 'device' => true, )); } private function renderFeedPage(PhabricatorProject $project) { $query = new PhabricatorFeedQuery(); $query->setFilterPHIDs(array($project->getPHID())); $query->setViewer($this->getRequest()->getUser()); $query->setLimit(100); $stories = $query->execute(); if (!$stories) { return pht('There are no stories about this project.'); } return $this->renderStories($stories); } private function renderStories(array $stories) { assert_instances_of($stories, 'PhabricatorFeedStory'); $builder = new PhabricatorFeedBuilder($stories); $builder->setUser($this->getRequest()->getUser()); $builder->setShowHovercards(true); $view = $builder->buildView(); return phutil_tag_div( 'profile-feed', $view->render()); } private function renderTasksPage(PhabricatorProject $project) { $user = $this->getRequest()->getUser(); $query = id(new ManiphestTaskQuery()) ->setViewer($user) ->withAnyProjects(array($project->getPHID())) ->withStatuses(ManiphestTaskStatus::getOpenStatusConstants()) ->setOrderBy(ManiphestTaskQuery::ORDER_PRIORITY) ->setLimit(10); $tasks = $query->execute(); $phids = mpull($tasks, 'getOwnerPHID'); $phids = array_merge( $phids, array_mergev(mpull($tasks, 'getProjectPHIDs'))); $phids = array_filter($phids); $handles = $this->loadViewerHandles($phids); $task_list = new ManiphestTaskListView(); $task_list->setUser($user); $task_list->setTasks($tasks); $task_list->setHandles($handles); $phid = $project->getPHID(); $view_uri = urisprintf( '/maniphest/?statuses=%s&allProjects=%s#R', implode(',', ManiphestTaskStatus::getOpenStatusConstants()), $phid); $create_uri = '/maniphest/task/create/?projects='.$phid; $icon = id(new PHUIIconView()) ->setIconFont('fa-list'); $button_view = id(new PHUIButtonView()) ->setTag('a') ->setText(pht('View All')) ->setHref($view_uri) ->setIcon($icon); $icon_new = id(new PHUIIconView()) ->setIconFont('fa-plus'); $button_add = id(new PHUIButtonView()) ->setTag('a') ->setText(pht('New Task')) ->setHref($create_uri) ->setIcon($icon_new); $header = id(new PHUIHeaderView()) ->setHeader(pht('Open Tasks')) ->addActionLink($button_add) ->addActionLink($button_view); $content = id(new PHUIObjectBoxView()) ->setHeader($header) ->appendChild($task_list); return $content; } private function buildActionListView(PhabricatorProject $project) { $request = $this->getRequest(); $viewer = $request->getUser(); $id = $project->getID(); $view = id(new PhabricatorActionListView()) ->setUser($viewer) ->setObject($project) ->setObjectURI($request->getRequestURI()); $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, $project, PhabricatorPolicyCapability::CAN_EDIT); $view->addAction( id(new PhabricatorActionView()) ->setName(pht('Edit Project')) ->setIcon('fa-pencil') ->setHref($this->getApplicationURI("edit/{$id}/"))); $view->addAction( id(new PhabricatorActionView()) ->setName(pht('Edit Members')) ->setIcon('fa-users') ->setHref($this->getApplicationURI("members/{$id}/")) ->setDisabled(!$can_edit) ->setWorkflow(!$can_edit)); $action = null; if (!$project->isUserMember($viewer->getPHID())) { $can_join = PhabricatorPolicyFilter::hasCapability( $viewer, $project, PhabricatorPolicyCapability::CAN_JOIN); $action = id(new PhabricatorActionView()) ->setUser($viewer) ->setRenderAsForm(true) ->setHref('/project/update/'.$project->getID().'/join/') ->setIcon('fa-plus') ->setDisabled(!$can_join) ->setName(pht('Join Project')); } else { $action = id(new PhabricatorActionView()) ->setWorkflow(true) ->setHref('/project/update/'.$project->getID().'/leave/') ->setIcon('fa-times') ->setName(pht('Leave Project...')); } $view->addAction($action); return $view; } private function buildPropertyListView( PhabricatorProject $project, PhabricatorActionListView $actions) { $request = $this->getRequest(); $viewer = $request->getUser(); $this->loadHandles($project->getMemberPHIDs()); $view = id(new PHUIPropertyListView()) ->setUser($viewer) ->setObject($project) ->setActionList($actions); $view->addProperty( pht('Members'), $project->getMemberPHIDs() ? $this->renderHandlesForPHIDs($project->getMemberPHIDs(), ',') : phutil_tag('em', array(), pht('None'))); $field_list = PhabricatorCustomField::getObjectFields( $project, PhabricatorCustomField::ROLE_VIEW); $field_list->appendFieldsToPropertyList($project, $viewer, $view); return $view; } } diff --git a/src/applications/project/phid/PhabricatorProjectPHIDTypeColumn.php b/src/applications/project/phid/PhabricatorProjectPHIDTypeColumn.php index 63f2db084c..410800ea25 100644 --- a/src/applications/project/phid/PhabricatorProjectPHIDTypeColumn.php +++ b/src/applications/project/phid/PhabricatorProjectPHIDTypeColumn.php @@ -1,42 +1,46 @@ <?php final class PhabricatorProjectPHIDTypeColumn extends PhabricatorPHIDType { const TYPECONST = 'PCOL'; public function getTypeConstant() { return self::TYPECONST; } public function getTypeName() { return pht('Project Column'); } public function newObject() { return new PhabricatorProjectColumn(); } + public function getTypeIcon() { + return 'fa-columns bluegrey'; + } + protected function buildQueryForObjects( PhabricatorObjectQuery $query, array $phids) { return id(new PhabricatorProjectColumnQuery()) ->withPHIDs($phids); } public function loadHandles( PhabricatorHandleQuery $query, array $handles, array $objects) { foreach ($handles as $phid => $handle) { $column = $objects[$phid]; $handle->setName($column->getDisplayName()); $handle->setURI('/project/board/'.$column->getProject()->getID().'/'); $handle->setDisabled( $column->getStatus() == PhabricatorProjectColumn::STATUS_DELETED); } } } diff --git a/src/applications/project/phid/PhabricatorProjectPHIDTypeProject.php b/src/applications/project/phid/PhabricatorProjectPHIDTypeProject.php index 41a86f1d9b..0699ca74f4 100644 --- a/src/applications/project/phid/PhabricatorProjectPHIDTypeProject.php +++ b/src/applications/project/phid/PhabricatorProjectPHIDTypeProject.php @@ -1,109 +1,109 @@ <?php final class PhabricatorProjectPHIDTypeProject extends PhabricatorPHIDType { const TYPECONST = 'PROJ'; public function getTypeConstant() { return self::TYPECONST; } public function getTypeName() { return pht('Project'); } public function getPHIDTypeApplicationClass() { return 'PhabricatorApplicationProject'; } public function getTypeIcon() { - return 'policy-project'; + return 'fa-briefcase bluegrey'; } public function newObject() { return new PhabricatorProject(); } protected function buildQueryForObjects( PhabricatorObjectQuery $query, array $phids) { return id(new PhabricatorProjectQuery()) ->withPHIDs($phids) ->needImages(true); } public function loadHandles( PhabricatorHandleQuery $query, array $handles, array $objects) { foreach ($handles as $phid => $handle) { $project = $objects[$phid]; $name = $project->getName(); $id = $project->getID(); $handle->setName($name); $handle->setObjectName('#'.rtrim($project->getPhrictionSlug(), '/')); $handle->setURI("/project/view/{$id}/"); $handle->setImageURI($project->getProfileImageURI()); if ($project->isArchived()) { $handle->setStatus(PhabricatorObjectHandleStatus::STATUS_CLOSED); } } } public static function getProjectMonogramPatternFragment() { // NOTE: See some discussion in ProjectRemarkupRule. return '[^\s,#]+'; } public function canLoadNamedObject($name) { $fragment = self::getProjectMonogramPatternFragment(); return preg_match('/^#'.$fragment.'$/i', $name); } public function loadNamedObjects( PhabricatorObjectQuery $query, array $names) { // If the user types "#YoloSwag", we still want to match "#yoloswag", so // we normalize, query, and then map back to the original inputs. $map = array(); foreach ($names as $key => $slug) { $map[$this->normalizeSlug(substr($slug, 1))][] = $slug; } $projects = id(new PhabricatorProjectQuery()) ->setViewer($query->getViewer()) ->withPhrictionSlugs(array_keys($map)) ->execute(); $result = array(); foreach ($projects as $project) { $slugs = array($project->getPhrictionSlug()); foreach ($slugs as $slug) { foreach ($map[$slug] as $original) { $result[$original] = $project; } } } return $result; } private function normalizeSlug($slug) { // NOTE: We're using phutil_utf8_strtolower() (and not PhabricatorSlug's // normalize() method) because this normalization should be only somewhat // liberal. We want "#YOLO" to match against "#yolo", but "#\\yo!!lo" // should not. normalize() strips out most punctuation and leads to // excessively aggressive matches. return phutil_utf8_strtolower($slug).'/'; } } diff --git a/src/applications/releeph/controller/branch/ReleephBranchViewController.php b/src/applications/releeph/controller/branch/ReleephBranchViewController.php index 09f1534f26..f282bc9883 100644 --- a/src/applications/releeph/controller/branch/ReleephBranchViewController.php +++ b/src/applications/releeph/controller/branch/ReleephBranchViewController.php @@ -1,202 +1,202 @@ <?php final class ReleephBranchViewController extends ReleephBranchController implements PhabricatorApplicationSearchResultsControllerInterface { private $queryKey; private $branchID; public function shouldAllowPublic() { return true; } public function willProcessRequest(array $data) { $this->branchID = $data['branchID']; $this->queryKey = idx($data, 'queryKey'); } public function processRequest() { $request = $this->getRequest(); $viewer = $request->getUser(); $branch = id(new ReleephBranchQuery()) ->setViewer($viewer) ->withIDs(array($this->branchID)) ->executeOne(); if (!$branch) { return new Aphront404Response(); } $this->setBranch($branch); $controller = id(new PhabricatorApplicationSearchController($request)) ->setPreface($this->renderPreface()) ->setQueryKey($this->queryKey) ->setSearchEngine($this->getSearchEngine()) ->setNavigation($this->buildSideNavView()); return $this->delegateToController($controller); } public function renderResultsList( array $requests, PhabricatorSavedQuery $query) { assert_instances_of($requests, 'ReleephRequest'); $viewer = $this->getRequest()->getUser(); // TODO: This is generally a bit sketchy, but we don't do this kind of // thing elsewhere at the moment. For the moment it shouldn't be hugely // costly, and we can batch things later. Generally, this commits fewer // sins than the old code did. $engine = id(new PhabricatorMarkupEngine()) ->setViewer($viewer); $list = array(); foreach ($requests as $pull) { $field_list = PhabricatorCustomField::getObjectFields( $pull, PhabricatorCustomField::ROLE_VIEW); $field_list ->setViewer($viewer) ->readFieldsFromStorage($pull); foreach ($field_list->getFields() as $field) { if ($field->shouldMarkup()) { $field->setMarkupEngine($engine); } } $list[] = id(new ReleephRequestView()) ->setUser($viewer) ->setCustomFields($field_list) ->setPullRequest($pull) ->setIsListView(true); } // This is quite sketchy, but the list has not actually rendered yet, so // this still allows us to batch the markup rendering. $engine->process(); return $list; } public function buildSideNavView($for_app = false) { $user = $this->getRequest()->getUser(); $nav = new AphrontSideNavFilterView(); $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); $this->getSearchEngine()->addNavigationItems($nav->getMenu()); $nav->selectFilter(null); return $nav; } private function getSearchEngine() { $branch = $this->getBranch(); return id(new ReleephRequestSearchEngine()) ->setBranch($branch) ->setBaseURI($this->getApplicationURI('branch/'.$branch->getID().'/')) ->setViewer($this->getRequest()->getUser()); } public function buildApplicationCrumbs() { $crumbs = parent::buildApplicationCrumbs(); $branch = $this->getBranch(); if ($branch) { $pull_uri = $this->getApplicationURI('branch/pull/'.$branch->getID().'/'); $crumbs->addAction( id(new PHUIListItemView()) ->setHref($pull_uri) ->setName(pht('New Pull Request')) ->setIcon('fa-plus-square') ->setDisabled(!$branch->isActive())); } return $crumbs; } private function renderPreface() { $viewer = $this->getRequest()->getUser(); $branch = $this->getBranch(); $id = $branch->getID(); $header = id(new PHUIHeaderView()) ->setHeader($branch->getDisplayName()) ->setUser($viewer) ->setPolicyObject($branch); if ($branch->getIsActive()) { - $header->setStatus('oh-ok', '', pht('Active')); + $header->setStatus('fa-check', 'bluegrey', pht('Active')); } else { - $header->setStatus('policy-noone', '', pht('Closed')); + $header->setStatus('fa-ban', 'dark', pht('Closed')); } $actions = id(new PhabricatorActionListView()) ->setUser($viewer) ->setObject($branch) ->setObjectURI($this->getRequest()->getRequestURI()); $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, $branch, PhabricatorPolicyCapability::CAN_EDIT); $edit_uri = $this->getApplicationURI("branch/edit/{$id}/"); $close_uri = $this->getApplicationURI("branch/close/{$id}/"); $reopen_uri = $this->getApplicationURI("branch/re-open/{$id}/"); $history_uri = $this->getApplicationURI("branch/{$id}/history/"); $actions->addAction( id(new PhabricatorActionView()) ->setName(pht('Edit Branch')) ->setHref($edit_uri) ->setIcon('fa-pencil') ->setDisabled(!$can_edit) ->setWorkflow(!$can_edit)); if ($branch->getIsActive()) { $actions->addAction( id(new PhabricatorActionView()) ->setName(pht('Close Branch')) ->setHref($close_uri) ->setIcon('fa-times') ->setDisabled(!$can_edit) ->setWorkflow(true)); } else { $actions->addAction( id(new PhabricatorActionView()) ->setName(pht('Reopen Branch')) ->setHref($reopen_uri) ->setIcon('fa-plus') ->setUser($viewer) ->setDisabled(!$can_edit) ->setWorkflow(true)); } $actions->addAction( id(new PhabricatorActionView()) ->setName(pht('View History')) ->setHref($history_uri) ->setIcon('fa-list')); $properties = id(new PHUIPropertyListView()) ->setUser($viewer) ->setObject($branch) ->setActionList($actions); $properties->addProperty( pht('Branch'), $branch->getName()); return id(new PHUIObjectBoxView()) ->setHeader($header) ->addPropertyList($properties); } } diff --git a/src/applications/releeph/controller/product/ReleephProductViewController.php b/src/applications/releeph/controller/product/ReleephProductViewController.php index 22b852d72a..2d72268a71 100644 --- a/src/applications/releeph/controller/product/ReleephProductViewController.php +++ b/src/applications/releeph/controller/product/ReleephProductViewController.php @@ -1,251 +1,251 @@ <?php final class ReleephProductViewController extends ReleephProductController implements PhabricatorApplicationSearchResultsControllerInterface { private $productID; private $queryKey; public function shouldAllowPublic() { return true; } public function willProcessRequest(array $data) { $this->productID = idx($data, 'projectID'); $this->queryKey = idx($data, 'queryKey'); } public function processRequest() { $request = $this->getRequest(); $viewer = $request->getUser(); $product = id(new ReleephProductQuery()) ->setViewer($viewer) ->withIDs(array($this->productID)) ->executeOne(); if (!$product) { return new Aphront404Response(); } $this->setProduct($product); $controller = id(new PhabricatorApplicationSearchController($request)) ->setQueryKey($this->queryKey) ->setPreface($this->renderPreface()) ->setSearchEngine( id(new ReleephBranchSearchEngine()) ->setProduct($product)) ->setNavigation($this->buildSideNavView()); return $this->delegateToController($controller); } public function renderResultsList( array $branches, PhabricatorSavedQuery $saved) { assert_instances_of($branches, 'ReleephBranch'); $viewer = $this->getRequest()->getUser(); $products = mpull($branches, 'getProduct'); $repo_phids = mpull($products, 'getRepositoryPHID'); $repos = id(new PhabricatorRepositoryQuery()) ->setViewer($viewer) ->withPHIDs($repo_phids) ->execute(); $repos = mpull($repos, null, 'getPHID'); $phids = mpull($branches, 'getCreatedByUserPHID'); $this->loadHandles($phids); $requests = array(); if ($branches) { $requests = id(new ReleephRequestQuery()) ->setViewer($viewer) ->withBranchIDs(mpull($branches, 'getID')) ->withStatus(ReleephRequestQuery::STATUS_OPEN) ->execute(); $requests = mgroup($requests, 'getBranchID'); } $list = id(new PHUIObjectItemListView()) ->setUser($viewer); foreach ($branches as $branch) { $diffusion_href = null; $repo = idx($repos, $branch->getProduct()->getRepositoryPHID()); if ($repo) { $drequest = DiffusionRequest::newFromDictionary( array( 'user' => $viewer, 'repository' => $repo, )); $diffusion_href = $drequest->generateURI( array( 'action' => 'branch', 'branch' => $branch->getName(), )); } $branch_link = $branch->getName(); if ($diffusion_href) { $branch_link = phutil_tag( 'a', array( 'href' => $diffusion_href, ), $branch_link); } $item = id(new PHUIObjectItemView()) ->setHeader($branch->getDisplayName()) ->setHref($this->getApplicationURI('branch/'.$branch->getID().'/')) ->addAttribute($branch_link); if (!$branch->getIsActive()) { $item->setDisabled(true); } $commit = $branch->getCutPointCommit(); if ($commit) { $item->addIcon( 'none', phabricator_datetime($commit->getEpoch(), $viewer)); } $open_count = count(idx($requests, $branch->getID(), array())); if ($open_count) { $item->setBarColor('orange'); $item->addIcon( 'fa-code-fork', pht('%d Open Pull Request(s)', new PhutilNumber($open_count))); } $list->addItem($item); } return $list; } public function buildSideNavView($for_app = false) { $viewer = $this->getRequest()->getUser(); $product = $this->getProduct(); $nav = new AphrontSideNavFilterView(); $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); if ($for_app) { $nav->addFilter('product/create/', pht('Create Product')); } id(new ReleephBranchSearchEngine()) ->setProduct($product) ->setViewer($viewer) ->addNavigationItems($nav->getMenu()); $nav->selectFilter(null); return $nav; } public function buildApplicationCrumbs() { $crumbs = parent::buildApplicationCrumbs(); $product = $this->getProduct(); if ($product) { $crumbs->addAction( id(new PHUIListItemView()) ->setHref($product->getURI('cutbranch/')) ->setName(pht('Cut New Branch')) ->setIcon('fa-plus')); } return $crumbs; } private function renderPreface() { $viewer = $this->getRequest()->getUser(); $product = $this->getProduct(); $id = $product->getID(); $header = id(new PHUIHeaderView()) ->setHeader($product->getName()) ->setUser($viewer) ->setPolicyObject($product); if ($product->getIsActive()) { - $header->setStatus('oh-ok', '', pht('Active')); + $header->setStatus('fa-check', 'bluegrey', pht('Active')); } else { - $header->setStatus('policy-noone', '', pht('Inactive')); + $header->setStatus('fa-ban', 'dark', pht('Inactive')); } $actions = id(new PhabricatorActionListView()) ->setUser($viewer) ->setObject($product) ->setObjectURI($this->getRequest()->getRequestURI()); $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, $product, PhabricatorPolicyCapability::CAN_EDIT); $edit_uri = $this->getApplicationURI("product/{$id}/edit/"); $history_uri = $this->getApplicationURI("product/{$id}/history/"); $actions->addAction( id(new PhabricatorActionView()) ->setName(pht('Edit Product')) ->setHref($edit_uri) ->setIcon('fa-pencil') ->setDisabled(!$can_edit) ->setWorkflow(!$can_edit)); if ($product->getIsActive()) { $status_name = pht('Deactivate Product'); $status_href = "product/{$id}/action/deactivate/"; $status_icon = 'fa-times'; } else { $status_name = pht('Reactivate Product'); $status_href = "product/{$id}/action/activate/"; $status_icon = 'fa-plus-circle-o'; } $actions->addAction( id(new PhabricatorActionView()) ->setName($status_name) ->setHref($this->getApplicationURI($status_href)) ->setIcon($status_icon) ->setDisabled(!$can_edit) ->setWorkflow(true)); $actions->addAction( id(new PhabricatorActionView()) ->setName(pht('View History')) ->setHref($history_uri) ->setIcon('fa-list')); $properties = id(new PHUIPropertyListView()) ->setUser($viewer) ->setObject($product); $properties->addProperty( pht('Repository'), $product->getRepository()->getName()); $properties->setActionList($actions); $pushers = $product->getPushers(); if ($pushers) { $this->loadHandles($pushers); $properties->addProperty( pht('Pushers'), $this->renderHandlesForPHIDs($pushers)); } return id(new PHUIObjectBoxView()) ->setHeader($header) ->addPropertyList($properties); } } diff --git a/src/applications/slowvote/controller/PhabricatorSlowvotePollController.php b/src/applications/slowvote/controller/PhabricatorSlowvotePollController.php index 884cdec99d..0c72687d1a 100644 --- a/src/applications/slowvote/controller/PhabricatorSlowvotePollController.php +++ b/src/applications/slowvote/controller/PhabricatorSlowvotePollController.php @@ -1,195 +1,196 @@ <?php /** * @group slowvote */ final class PhabricatorSlowvotePollController extends PhabricatorSlowvoteController { private $id; public function willProcessRequest(array $data) { $this->id = $data['id']; } public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); $poll = id(new PhabricatorSlowvoteQuery()) ->setViewer($user) ->withIDs(array($this->id)) ->needOptions(true) ->needChoices(true) ->needViewerChoices(true) ->executeOne(); if (!$poll) { return new Aphront404Response(); } $poll_view = id(new SlowvoteEmbedView()) ->setHeadless(true) ->setUser($user) ->setPoll($poll); if ($request->isAjax()) { return id(new AphrontAjaxResponse()) ->setContent( array( 'pollID' => $poll->getID(), 'contentHTML' => $poll_view->render(), )); } - $header_icon = $poll->getIsClosed() ? 'oh-closed' : 'open'; + $header_icon = $poll->getIsClosed() ? 'fa-ban' : 'fa-circle-o'; $header_name = $poll->getIsClosed() ? pht('Closed') : pht('Open'); + $header_color = $poll->getIsClosed() ? 'dark' : 'bluegrey'; $header = id(new PHUIHeaderView()) ->setHeader($poll->getQuestion()) ->setUser($user) - ->setStatus($header_icon, '', $header_name) + ->setStatus($header_icon, $header_color, $header_name) ->setPolicyObject($poll); $actions = $this->buildActionView($poll); $properties = $this->buildPropertyView($poll, $actions); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb('V'.$poll->getID()); $xactions = $this->buildTransactions($poll); $add_comment = $this->buildCommentForm($poll); $object_box = id(new PHUIObjectBoxView()) ->setHeader($header) ->addPropertyList($properties); return $this->buildApplicationPage( array( $crumbs, $object_box, phutil_tag( 'div', array( 'class' => 'mlt mml mmr', ), $poll_view), $xactions, $add_comment, ), array( 'title' => 'V'.$poll->getID().' '.$poll->getQuestion(), 'device' => true, 'pageObjects' => array($poll->getPHID()), )); } private function buildActionView(PhabricatorSlowvotePoll $poll) { $viewer = $this->getRequest()->getUser(); $view = id(new PhabricatorActionListView()) ->setUser($viewer) ->setObject($poll); $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, $poll, PhabricatorPolicyCapability::CAN_EDIT); $is_closed = $poll->getIsClosed(); $close_poll_text = $is_closed ? pht('Reopen Poll') : pht('Close Poll'); $close_poll_icon = $is_closed ? 'fa-play-circle-o' : 'fa-ban'; $view->addAction( id(new PhabricatorActionView()) ->setName(pht('Edit Poll')) ->setIcon('fa-pencil') ->setHref($this->getApplicationURI('edit/'.$poll->getID().'/')) ->setDisabled(!$can_edit) ->setWorkflow(!$can_edit)); $view->addAction( id(new PhabricatorActionView()) ->setName($close_poll_text) ->setIcon($close_poll_icon) ->setHref($this->getApplicationURI('close/'.$poll->getID().'/')) ->setDisabled(!$can_edit) ->setWorkflow(true)); return $view; } private function buildPropertyView( PhabricatorSlowvotePoll $poll, PhabricatorActionListView $actions) { $viewer = $this->getRequest()->getUser(); $view = id(new PHUIPropertyListView()) ->setUser($viewer) ->setObject($poll) ->setActionList($actions); $view->invokeWillRenderEvent(); if (strlen($poll->getDescription())) { $view->addTextContent( $output = PhabricatorMarkupEngine::renderOneObject( id(new PhabricatorMarkupOneOff())->setContent( $poll->getDescription()), 'default', $viewer)); } return $view; } private function buildTransactions(PhabricatorSlowvotePoll $poll) { $viewer = $this->getRequest()->getUser(); $xactions = id(new PhabricatorSlowvoteTransactionQuery()) ->setViewer($viewer) ->withObjectPHIDs(array($poll->getPHID())) ->execute(); $engine = id(new PhabricatorMarkupEngine()) ->setViewer($viewer); foreach ($xactions as $xaction) { if ($xaction->getComment()) { $engine->addObject( $xaction->getComment(), PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT); } } $engine->process(); $timeline = id(new PhabricatorApplicationTransactionView()) ->setUser($viewer) ->setObjectPHID($poll->getPHID()) ->setTransactions($xactions) ->setMarkupEngine($engine); return $timeline; } private function buildCommentForm(PhabricatorSlowvotePoll $poll) { $viewer = $this->getRequest()->getUser(); $is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business'); $add_comment_header = $is_serious ? pht('Add Comment') : pht('Enter Deliberations'); $draft = PhabricatorDraft::newFromUserAndKey($viewer, $poll->getPHID()); return id(new PhabricatorApplicationTransactionCommentView()) ->setUser($viewer) ->setObjectPHID($poll->getPHID()) ->setDraft($draft) ->setHeaderText($add_comment_header) ->setAction($this->getApplicationURI('/comment/'.$poll->getID().'/')) ->setSubmitButtonName(pht('Add Comment')); } } diff --git a/src/applications/typeahead/controller/PhabricatorTypeaheadCommonDatasourceController.php b/src/applications/typeahead/controller/PhabricatorTypeaheadCommonDatasourceController.php index ad3e45ffb9..8ed9e92fbf 100644 --- a/src/applications/typeahead/controller/PhabricatorTypeaheadCommonDatasourceController.php +++ b/src/applications/typeahead/controller/PhabricatorTypeaheadCommonDatasourceController.php @@ -1,439 +1,439 @@ <?php final class PhabricatorTypeaheadCommonDatasourceController extends PhabricatorTypeaheadDatasourceController { private $type; public function shouldAllowPublic() { return true; } public function willProcessRequest(array $data) { $this->type = $data['type']; } public function processRequest() { $request = $this->getRequest(); $viewer = $request->getUser(); $query = $request->getStr('q'); $raw_query = $request->getStr('raw'); $need_rich_data = false; $need_users = false; $need_agents = false; $need_applications = false; $need_lists = false; $need_projs = false; $need_repos = false; $need_packages = false; $need_upforgrabs = false; $need_arcanist_projects = false; $need_noproject = false; $need_symbols = false; $need_jump_objects = false; $need_build_plans = false; $need_task_priority = false; $need_macros = false; $need_legalpad_documents = false; switch ($this->type) { case 'mainsearch': $need_users = true; $need_applications = true; $need_rich_data = true; $need_symbols = true; $need_projs = true; $need_jump_objects = true; break; case 'searchowner': $need_users = true; $need_upforgrabs = true; break; case 'searchproject': $need_projs = true; $need_noproject = true; break; case 'users': case 'accounts': case 'authors': $need_users = true; break; case 'mailable': case 'allmailable': $need_users = true; $need_lists = true; $need_projs = true; break; case 'projects': $need_projs = true; break; case 'usersorprojects': case 'accountsorprojects': $need_users = true; $need_projs = true; break; case 'usersprojectsorpackages': $need_users = true; $need_projs = true; $need_packages = true; break; case 'repositories': $need_repos = true; break; case 'packages': $need_packages = true; break; case 'arcanistprojects': $need_arcanist_projects = true; break; case 'buildplans': $need_build_plans = true; break; case 'taskpriority': $need_task_priority = true; break; case 'macros': $need_macros = true; break; case 'legalpaddocuments': $need_legalpad_documents = true; break; } $results = array(); if ($need_upforgrabs) { $results[] = id(new PhabricatorTypeaheadResult()) ->setName('upforgrabs (Up For Grabs)') ->setPHID(ManiphestTaskOwner::OWNER_UP_FOR_GRABS); } if ($need_noproject) { $results[] = id(new PhabricatorTypeaheadResult()) ->setName('noproject (No Project)') ->setPHID(ManiphestTaskOwner::PROJECT_NO_PROJECT); } if ($need_users) { $columns = array( 'isSystemAgent', 'isAdmin', 'isDisabled', 'userName', 'realName', 'phid'); if ($query) { // This is an arbitrary limit which is just larger than any limit we // actually use in the application. // TODO: The datasource should pass this in the query. $limit = 15; $user_table = new PhabricatorUser(); $conn_r = $user_table->establishConnection('r'); $ids = queryfx_all( $conn_r, 'SELECT id FROM %T WHERE username LIKE %> ORDER BY username ASC LIMIT %d', $user_table->getTableName(), $query, $limit); $ids = ipull($ids, 'id'); if (count($ids) < $limit) { // If we didn't find enough username hits, look for real name hits. // We need to pull the entire pagesize so that we end up with the // right number of items if this query returns many duplicate IDs // that we've already selected. $realname_ids = queryfx_all( $conn_r, 'SELECT DISTINCT userID FROM %T WHERE token LIKE %> ORDER BY token ASC LIMIT %d', PhabricatorUser::NAMETOKEN_TABLE, $query, $limit); $realname_ids = ipull($realname_ids, 'userID'); $ids = array_merge($ids, $realname_ids); $ids = array_unique($ids); $ids = array_slice($ids, 0, $limit); } // Always add the logged-in user because some tokenizers autosort them // first. They'll be filtered out on the client side if they don't // match the query. $ids[] = $request->getUser()->getID(); if ($ids) { $users = id(new PhabricatorUser())->loadColumnsWhere( $columns, 'id IN (%Ld)', $ids); } else { $users = array(); } } else { $users = id(new PhabricatorUser())->loadColumns($columns); } if ($need_rich_data) { $phids = mpull($users, 'getPHID'); $handles = $this->loadViewerHandles($phids); } foreach ($users as $user) { $closed = null; if ($user->getIsDisabled()) { $closed = pht('Disabled'); } else if ($user->getIsSystemAgent()) { $closed = pht('Bot/Script'); } $result = id(new PhabricatorTypeaheadResult()) ->setName($user->getFullName()) ->setURI('/p/'.$user->getUsername()) ->setPHID($user->getPHID()) ->setPriorityString($user->getUsername()) - ->setIcon('policy-all') + ->setIcon('fa-user bluegrey') ->setPriorityType('user') ->setClosed($closed); if ($need_rich_data) { $display_type = 'User'; if ($user->getIsAdmin()) { $display_type = 'Administrator'; } $result->setDisplayType($display_type); $result->setImageURI($handles[$user->getPHID()]->getImageURI()); } $results[] = $result; } } if ($need_lists) { $lists = id(new PhabricatorMailingListQuery()) ->setViewer($viewer) ->execute(); foreach ($lists as $list) { $results[] = id(new PhabricatorTypeaheadResult()) ->setName($list->getName()) ->setURI($list->getURI()) ->setPHID($list->getPHID()); } } if ($need_build_plans) { $plans = id(new HarbormasterBuildPlanQuery()) ->setViewer($viewer) ->execute(); foreach ($plans as $plan) { $results[] = id(new PhabricatorTypeaheadResult()) ->setName($plan->getName()) ->setPHID($plan->getPHID()); } } if ($need_task_priority) { $priority_map = ManiphestTaskPriority::getTaskPriorityMap(); foreach ($priority_map as $value => $name) { // NOTE: $value is not a phid but is unique. This'll work. $results[] = id(new PhabricatorTypeaheadResult()) ->setPHID($value) ->setName($name); } } if ($need_macros) { $macros = id(new PhabricatorMacroQuery()) ->setViewer($viewer) ->withStatus(PhabricatorMacroQuery::STATUS_ACTIVE) ->execute(); $macros = mpull($macros, 'getName', 'getPHID'); foreach ($macros as $phid => $name) { $results[] = id(new PhabricatorTypeaheadResult()) ->setPHID($phid) ->setName($name); } } if ($need_legalpad_documents) { $documents = id(new LegalpadDocumentQuery()) ->setViewer($viewer) ->execute(); $documents = mpull($documents, 'getTitle', 'getPHID'); foreach ($documents as $phid => $title) { $results[] = id(new PhabricatorTypeaheadResult()) ->setPHID($phid) ->setName($title); } } if ($need_projs) { $projs = id(new PhabricatorProjectQuery()) ->setViewer($viewer) ->needImages(true) ->execute(); foreach ($projs as $proj) { $closed = null; if ($proj->isArchived()) { $closed = pht('Archived'); } $proj_result = id(new PhabricatorTypeaheadResult()) ->setName($proj->getName()) ->setDisplayType("Project") ->setURI('/project/view/'.$proj->getID().'/') ->setPHID($proj->getPHID()) - ->setIcon('policy-project') + ->setIcon('fa-briefcase bluegrey') ->setClosed($closed); $proj_result->setImageURI($proj->getProfileImageURI()); $results[] = $proj_result; } } if ($need_repos) { $repos = id(new PhabricatorRepositoryQuery()) ->setViewer($viewer) ->execute(); foreach ($repos as $repo) { $results[] = id(new PhabricatorTypeaheadResult()) ->setName('r'.$repo->getCallsign().' ('.$repo->getName().')') ->setURI('/diffusion/'.$repo->getCallsign().'/') ->setPHID($repo->getPHID()) ->setPriorityString('r'.$repo->getCallsign()); } } if ($need_packages) { $packages = id(new PhabricatorOwnersPackage())->loadAll(); foreach ($packages as $package) { $results[] = id(new PhabricatorTypeaheadResult()) ->setIcon('pl-testplan') ->setName($package->getName()) ->setURI('/owners/package/'.$package->getID().'/') ->setPHID($package->getPHID()); } } if ($need_arcanist_projects) { $arcprojs = id(new PhabricatorRepositoryArcanistProject())->loadAll(); foreach ($arcprojs as $proj) { $results[] = id(new PhabricatorTypeaheadResult()) ->setName($proj->getName()) ->setPHID($proj->getPHID()); } } if ($need_applications) { $applications = PhabricatorApplication::getAllInstalledApplications(); foreach ($applications as $application) { $uri = $application->getTypeaheadURI(); if (!$uri) { continue; } $name = $application->getName().' '.$application->getShortDescription(); $results[] = id(new PhabricatorTypeaheadResult()) ->setName($name) ->setURI($uri) ->setPHID($application->getPHID()) ->setPriorityString($application->getName()) ->setDisplayName($application->getName()) ->setDisplayType($application->getShortDescription()) ->setImageuRI($application->getIconURI()) ->setPriorityType('apps'); } } if ($need_symbols) { $symbols = id(new DiffusionSymbolQuery()) ->setNamePrefix($query) ->setLimit(15) ->needArcanistProjects(true) ->needRepositories(true) ->needPaths(true) ->execute(); foreach ($symbols as $symbol) { $lang = $symbol->getSymbolLanguage(); $name = $symbol->getSymbolName(); $type = $symbol->getSymbolType(); $proj = $symbol->getArcanistProject()->getName(); $results[] = id(new PhabricatorTypeaheadResult()) ->setName($name) ->setURI($symbol->getURI()) ->setPHID(md5($symbol->getURI())) // Just needs to be unique. ->setDisplayName($name) ->setDisplayType(strtoupper($lang).' '.ucwords($type).' ('.$proj.')') ->setPriorityType('symb'); } } if ($need_jump_objects) { $objects = id(new PhabricatorObjectQuery()) ->setViewer($viewer) ->withNames(array($raw_query)) ->execute(); if ($objects) { $handles = id(new PhabricatorHandleQuery()) ->setViewer($viewer) ->withPHIDs(mpull($objects, 'getPHID')) ->execute(); $handle = head($handles); if ($handle) { $results[] = id(new PhabricatorTypeaheadResult()) ->setName($handle->getFullName()) ->setDisplayType($handle->getTypeName()) ->setURI($handle->getURI()) ->setPHID($handle->getPHID()) ->setPriorityType('jump'); } } } $content = mpull($results, 'getWireFormat'); if ($request->isAjax()) { return id(new AphrontAjaxResponse())->setContent($content); } // If there's a non-Ajax request to this endpoint, show results in a tabular // format to make it easier to debug typeahead output. $rows = array(); foreach ($results as $result) { $wire = $result->getWireFormat(); $rows[] = $wire; } $table = new AphrontTableView($rows); $table->setHeaders( array( 'Name', 'URI', 'PHID', 'Priority', 'Display Name', 'Display Type', 'Image URI', 'Priority Type', )); $panel = new AphrontPanelView(); $panel->setHeader('Typeahead Results'); $panel->appendChild($table); return $this->buildStandardPageResponse( $panel, array( 'title' => 'Typeahead Results', )); } } diff --git a/src/infrastructure/celerity/CeleritySpriteGenerator.php b/src/infrastructure/celerity/CeleritySpriteGenerator.php index 92e8060888..6e0c995413 100644 --- a/src/infrastructure/celerity/CeleritySpriteGenerator.php +++ b/src/infrastructure/celerity/CeleritySpriteGenerator.php @@ -1,806 +1,762 @@ <?php final class CeleritySpriteGenerator { public function buildRemarkupSheet() { $scales = array( '1x' => 1, '2x' => 2, ); $sprites = array(); $template = id(new PhutilSprite()) ->setSourceSize(14, 14); $remarkup_icons = $this->getDirectoryList('remarkup_1x'); foreach ($remarkup_icons as $icon) { $prefix = 'remarkup_'; // Strip 'text_' from these file names. $class_name = substr($icon, 5); if ($class_name == 'fullscreen_off') { $tcss = '.remarkup-control-fullscreen-mode .remarkup-assist-fullscreen'; } else { $tcss = '.remarkup-assist-'.$class_name; } $sprite = id(clone $template) ->setName('remarkup-assist-'.$icon) ->setTargetCSS($tcss); foreach ($scales as $scale_key => $scale) { $path = $this->getPath($prefix.$scale_key.'/'.$icon.'.png'); $sprite->setSourceFile($path, $scale); } $sprites[] = $sprite; } $sheet = $this->buildSheet('remarkup', true); $sheet->setScales($scales); foreach ($sprites as $sprite) { $sheet->addSprite($sprite); } return $sheet; } public function buildActionsSheet() { $icons = $this->getDirectoryList('actions_white_1x'); $colors = array( 'dark', 'grey', 'white', ); $scales = array( '1x' => 1, '2x' => 2, ); $template = id(new PhutilSprite()) ->setSourceSize(24, 24); $sprites = array(); foreach ($colors as $color) { foreach ($icons as $icon) { $prefix = 'actions_'; if (strlen($color)) { $prefix .= $color.'_'; } $suffix = ''; if (strlen($color)) { $suffix = '-'.$color; } $sprite = id(clone $template) ->setName('actions-'.$icon.$suffix); $tcss = array(); $tcss[] = '.actions-'.$icon.$suffix; if ($color == 'dark') { $tcss[] = '.device-desktop '. '.actions-'.$icon.'-grey.phui-icon-view: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('actions', true); $sheet->setScales($scales); foreach ($sprites as $sprite) { $sheet->addSprite($sprite); } return $sheet; } public function buildMiniconsSheet() { $icons = $this->getDirectoryList('minicons_white_1x'); $colors = array( 'white', 'dark', ); $scales = array( '1x' => 1, '2x' => 2, ); $template = id(new PhutilSprite()) ->setSourceSize(16, 16); $sprites = array(); foreach ($colors as $color) { foreach ($icons as $icon) { $prefix = 'minicons_'; if (strlen($color)) { $prefix .= $color.'_'; } $suffix = ''; if (strlen($color)) { $suffix = '-'.$color; } $sprite = id(clone $template) ->setName('minicons-'.$icon.$suffix); $sprite->setTargetCSS('.minicons-'.$icon.$suffix); foreach ($scales as $scale_key => $scale) { $path = $this->getPath($prefix.$scale_key.'/'.$icon.'.png'); $sprite->setSourceFile($path, $scale); } $sprites[] = $sprite; } } $sheet = $this->buildSheet('minicons', true); $sheet->setScales($scales); foreach ($sprites as $sprite) { $sheet->addSprite($sprite); } return $sheet; } public function buildMenuSheet() { $sprites = array(); $sources = array( 'seen_read_all' => array( 'x' => 18, 'y' => 18, 'css' => '.alert-notifications .phabricator-main-menu-alert-icon', ), 'seen_have_unread' => array( 'x' => 18, 'y' => 18, 'css' => '.alert-notifications:hover .phabricator-main-menu-alert-icon', ), 'unseen_any' => array( 'x' => 18, 'y' => 18, 'css' => '.alert-notifications.alert-unread .phabricator-main-menu-alert-icon', ), 'arrow-right' => array( 'x' => 9, 'y' => 31, 'css' => '.phabricator-crumb-divider', ), 'search' => array( 'x' => 24, 'y' => 24, 'css' => '.menu-icon-search', ), 'search_blue' => array( 'x' => 24, 'y' => 24, 'css' => '.menu-icon-search-blue', ), 'new' => array( 'x' => 24, 'y' => 24, 'css' => '.menu-icon-new', ), 'new_blue' => array( 'x' => 24, 'y' => 24, 'css' => '.menu-icon-new-blue', ), 'app' => array( 'x' => 24, 'y' => 24, 'css' => '.menu-icon-app', ), 'app_blue' => array( 'x' => 24, 'y' => 24, 'css' => '.menu-icon-app-blue', ), 'logo' => array( 'x' => 149, 'y' => 26, 'css' => '.phabricator-main-menu-logo-image', ), 'conf-off' => array( 'x' => 18, 'y' => 18, 'css' => '.alert-notifications .phabricator-main-menu-message-icon', ), 'conf-hover' => array( 'x' => 18, 'y' => 18, 'css' => '.alert-notifications:hover .phabricator-main-menu-message-icon', ), 'conf-unseen' => array( 'x' => 18, 'y' => 18, 'css' => '.alert-notifications.message-unread '. '.phabricator-main-menu-message-icon', ), ); $scales = array( '1x' => 1, '2x' => 2, ); $template = new PhutilSprite(); foreach ($sources as $name => $spec) { $sprite = id(clone $template) ->setName($name) ->setSourceSize($spec['x'], $spec['y']) ->setTargetCSS($spec['css']); foreach ($scales as $scale_name => $scale) { $path = 'menu_'.$scale_name.'/'.$name.'.png'; $path = $this->getPath($path); $sprite->setSourceFile($path, $scale); } $sprites[] = $sprite; } $sheet = $this->buildSheet('menu', true); $sheet->setScales($scales); foreach ($sprites as $sprite) { $sheet->addSprite($sprite); } return $sheet; } public function buildTokenSheet() { $icons = $this->getDirectoryList('tokens_1x'); $scales = array( '1x' => 1, '2x' => 2, ); $template = id(new PhutilSprite()) ->setSourceSize(16, 16); $sprites = array(); $prefix = 'tokens_'; foreach ($icons as $icon) { $sprite = id(clone $template) ->setName('tokens-'.$icon) ->setTargetCSS('.tokens-'.$icon); foreach ($scales as $scale_key => $scale) { $path = $this->getPath($prefix.$scale_key.'/'.$icon.'.png'); $sprite->setSourceFile($path, $scale); } $sprites[] = $sprite; } $sheet = $this->buildSheet('tokens', true); $sheet->setScales($scales); foreach ($sprites as $sprite) { $sheet->addSprite($sprite); } return $sheet; } public function buildButtonBarSheet() { $icons = $this->getDirectoryList('button_bar_1x'); $scales = array( '1x' => 1, '2x' => 2, ); $template = id(new PhutilSprite()) ->setSourceSize(14, 14); $sprites = array(); $prefix = 'button_bar_'; foreach ($icons as $icon) { $sprite = id(clone $template) ->setName('buttonbar-'.$icon) ->setTargetCSS('.buttonbar-'.$icon); foreach ($scales as $scale_key => $scale) { $path = $this->getPath($prefix.$scale_key.'/'.$icon.'.png'); $sprite->setSourceFile($path, $scale); } $sprites[] = $sprite; } $sheet = $this->buildSheet('buttonbar', true); $sheet->setScales($scales); foreach ($sprites as $sprite) { $sheet->addSprite($sprite); } return $sheet; } public function buildProjectsSheet() { $icons = $this->getDirectoryList('projects_1x'); $scales = array( '1x' => 1, '2x' => 2, ); $template = id(new PhutilSprite()) ->setSourceSize(50, 50); $sprites = array(); $prefix = 'projects-'; foreach ($icons as $icon) { $sprite = id(clone $template) ->setName($prefix.$icon) ->setTargetCSS('.'.$prefix.$icon); foreach ($scales as $scale_key => $scale) { $path = $this->getPath('projects_'.$scale_key.'/'.$icon.'.png'); $sprite->setSourceFile($path, $scale); } $sprites[] = $sprite; } $sheet = $this->buildSheet('projects', true); $sheet->setScales($scales); foreach ($sprites as $sprite) { $sheet->addSprite($sprite); } return $sheet; } public function buildPaymentsSheet() { $icons = $this->getDirectoryList('payments_2x'); $scales = array( '2x' => 1, ); $template = id(new PhutilSprite()) ->setSourceSize(60, 32); $sprites = array(); $prefix = 'payments_'; foreach ($icons as $icon) { $sprite = id(clone $template) ->setName('payments-'.$icon) ->setTargetCSS('.payments-'.$icon); foreach ($scales as $scale_key => $scale) { $path = $this->getPath($prefix.$scale_key.'/'.$icon.'.png'); $sprite->setSourceFile($path, $scale); } $sprites[] = $sprite; } $sheet = $this->buildSheet('payments', true); $sheet->setScales($scales); foreach ($sprites as $sprite) { $sheet->addSprite($sprite); } return $sheet; } public function buildConpherenceSheet() { $name = 'conpherence'; $icons = $this->getDirectoryList($name.'_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 = $name.'_'; $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($name, true); $sheet->setScales($scales); foreach ($sprites as $sprite) { $sheet->addSprite($sprite); } return $sheet; } public function buildDocsSheet() { $icons = $this->getDirectoryList('docs_1x'); $scales = array( '1x' => 1, '2x' => 2, ); $template = id(new PhutilSprite()) ->setSourceSize(32, 32); $sprites = array(); $prefix = 'docs_'; foreach ($icons as $icon) { $sprite = id(clone $template) ->setName($prefix.$icon) ->setTargetCSS('.'.$prefix.$icon); foreach ($scales as $scale_key => $scale) { $path = $this->getPath($prefix.$scale_key.'/'.$icon.'.png'); $sprite->setSourceFile($path, $scale); } $sprites[] = $sprite; } $sheet = $this->buildSheet('docs', true); $sheet->setScales($scales); foreach ($sprites as $sprite) { $sheet->addSprite($sprite); } return $sheet; } public function buildLoginSheet() { $icons = $this->getDirectoryList('login_1x'); $scales = array( '1x' => 1, '2x' => 2, ); $template = id(new PhutilSprite()) ->setSourceSize(34, 34); $sprites = array(); $prefix = 'login_'; foreach ($icons as $icon) { $sprite = id(clone $template) ->setName('login-'.$icon) ->setTargetCSS('.login-'.$icon); foreach ($scales as $scale_key => $scale) { $path = $this->getPath($prefix.$scale_key.'/'.$icon.'.png'); $sprite->setSourceFile($path, $scale); } $sprites[] = $sprite; } $sheet = $this->buildSheet('login', true); $sheet->setScales($scales); foreach ($sprites as $sprite) { $sheet->addSprite($sprite); } return $sheet; } - public function buildStatusSheet() { - $icons = $this->getDirectoryList('status_1x'); - $scales = array( - '1x' => 1, - '2x' => 2, - ); - $template = id(new PhutilSprite()) - ->setSourceSize(14, 14); - - $sprites = array(); - $prefix = 'status_'; - - $pre_rule = ', .phuix-dropdown-menu .phabricator-action-view:hover '; - $extra_css = array( - 'policy-custom-white' => $pre_rule.'.status-policy-custom', - 'policy-all-white' => $pre_rule.'.status-policy-all', - 'policy-unknown-white' => $pre_rule.'.status-policy-unknown', - 'policy-admin-white' => $pre_rule.'.status-policy-admin', - 'policy-public-white' => $pre_rule.'.status-policy-public', - 'policy-project-white' => $pre_rule.'.status-policy-project', - 'policy-noone-white' => $pre_rule.'.status-policy-noone', - ); - - foreach ($icons as $icon) { - $sprite = id(clone $template) - ->setName('status-'.$icon) - ->setTargetCSS('.status-'.$icon.idx($extra_css, $icon)); - - foreach ($scales as $scale_key => $scale) { - $path = $this->getPath($prefix.$scale_key.'/'.$icon.'.png'); - $sprite->setSourceFile($path, $scale); - } - $sprites[] = $sprite; - } - - $sheet = $this->buildSheet('status', true); - $sheet->setScales($scales); - foreach ($sprites as $sprite) { - $sheet->addSprite($sprite); - } - - return $sheet; - } - public function buildGradientSheet() { $gradients = $this->getDirectoryList('gradients'); $template = new PhutilSprite(); $unusual_heights = array( 'dark-menu-label' => 25, 'breadcrumbs' => 31, 'menu-label' => 24, 'red-header' => 70, 'blue-header' => 70, 'green-header' => 70, 'yellow-header' => 70, 'grey-header' => 70, 'dark-grey-header' => 70, 'lightblue-header' => 240, ); $extra_css = array( 'dark-menu-label' => ', .phabricator-dark-menu .phui-list-item-type-label', 'menu-label' => ', .phabricator-side-menu .phui-list-item-type-label', ); $sprites = array(); foreach ($gradients as $gradient) { $path = $this->getPath('gradients/'.$gradient.'.png'); $sprite = id(clone $template) ->setName('gradient-'.$gradient) ->setSourceFile($path) ->setTargetCSS('.gradient-'.$gradient.idx($extra_css, $gradient)); $sprite->setSourceSize(4, idx($unusual_heights, $gradient, 26)); $sprites[] = $sprite; } $sheet = $this->buildSheet( 'gradient', false, PhutilSpriteSheet::TYPE_REPEAT_X, ', .phabricator-dark-menu .phui-list-item-type-label, '. '.phabricator-side-menu .phui-list-item-type-label'); foreach ($sprites as $sprite) { $sheet->addSprite($sprite); } return $sheet; } public function buildMainHeaderSheet() { $gradients = $this->getDirectoryList('main_header'); $template = new PhutilSprite(); $sprites = array(); foreach ($gradients as $gradient) { $path = $this->getPath('main_header/'.$gradient.'.png'); $sprite = id(clone $template) ->setName('main-header-'.$gradient) ->setSourceFile($path) ->setTargetCSS('.main-header-'.$gradient); $sprite->setSourceSize(6, 44); $sprites[] = $sprite; } $sheet = $this->buildSheet('main-header', false, PhutilSpriteSheet::TYPE_REPEAT_X); foreach ($sprites as $sprite) { $sheet->addSprite($sprite); } return $sheet; } public function buildAppsSheet() { return $this->buildAppsSheetVariant(1); } public function buildAppsLargeSheet() { return $this->buildAppsSheetVariant(2); } public function buildAppsXLargeSheet() { return $this->buildAppsSheetVariant(3); } private function buildAppsSheetVariant($variant) { if ($variant == 1) { $scales = array( '1x' => 1, '2x' => 2, ); $variant_name = 'apps'; $variant_short = ''; $size_x = 14; $size_y = 14; $colors = array( 'dark' => 'dark', ); } else if ($variant == 2) { $scales = array( '2x' => 1, '4x' => 2, ); $variant_name = 'apps-large'; $variant_short = '-large'; $size_x = 28; $size_y = 28; $colors = array( 'light' => 'lb', 'dark' => 'dark', 'blue' => 'blue', ); } else { $scales = array( '4x' => 1, ); $variant_name = 'apps-xlarge'; $variant_short = '-xlarge'; $size_x = 56; $size_y = 56; $colors = array( 'dark' => 'dark', ); } $apps = $this->getDirectoryList('apps_dark_1x'); $template = id(new PhutilSprite()) ->setSourceSize($size_x, $size_y); $sprites = array(); foreach ($apps as $app) { foreach ($colors as $color => $color_path) { $css = '.apps-'.$app.'-'.$color.$variant_short; if ($color == 'blue' && $variant_name == 'apps-large') { $css .= ', .phabricator-crumb-view:hover .apps-'.$app.'-dark-large'; } $sprite = id(clone $template) ->setName('apps-'.$app.'-'.$color.$variant_short) ->setTargetCSS($css); foreach ($scales as $scale_name => $scale) { $path = $this->getPath( 'apps_'.$color_path.'_'.$scale_name.'/'.$app.'.png'); $sprite->setSourceFile($path, $scale); } $sprites[] = $sprite; } } $sheet = $this->buildSheet($variant_name, count($scales) > 1); $sheet->setScales($scales); foreach ($sprites as $sprite) { $sheet->addSprite($sprite); } return $sheet; } private function getPath($to_path = null) { $root = dirname(phutil_get_library_root('phabricator')); return $root.'/resources/sprite/'.$to_path; } private function getDirectoryList($dir) { $path = $this->getPath($dir); $result = array(); $images = Filesystem::listDirectory($path, $include_hidden = false); foreach ($images as $image) { if (!preg_match('/\.png$/', $image)) { throw new Exception( "Expected file '{$image}' in '{$path}' to be a sprite source ". "ending in '.png'."); } $result[] = substr($image, 0, -4); } return $result; } private function buildSheet( $name, $has_retina, $type = null, $extra_css = '') { $sheet = new PhutilSpriteSheet(); $at = '@'; switch ($type) { case PhutilSpriteSheet::TYPE_STANDARD: default: $type = PhutilSpriteSheet::TYPE_STANDARD; $repeat_rule = 'no-repeat'; break; case PhutilSpriteSheet::TYPE_REPEAT_X: $repeat_rule = 'repeat-x'; break; case PhutilSpriteSheet::TYPE_REPEAT_Y: $repeat_rule = 'repeat-y'; break; } $retina_rules = null; if ($has_retina) { $retina_rules = <<<EOCSS @media only screen and (min-device-pixel-ratio: 1.5), only screen and (-webkit-min-device-pixel-ratio: 1.5) { .sprite-{$name}{$extra_css} { background-image: url(/rsrc/image/sprite-{$name}-X2.png); background-size: {X}px {Y}px; } } EOCSS; } $sheet->setSheetType($type); $sheet->setCSSHeader(<<<EOCSS /** * @provides sprite-{$name}-css * {$at}generated */ .sprite-{$name}{$extra_css} { background-image: url(/rsrc/image/sprite-{$name}.png); background-repeat: {$repeat_rule}; } {$retina_rules} EOCSS ); return $sheet; } } diff --git a/src/view/control/AphrontTokenizerTemplateView.php b/src/view/control/AphrontTokenizerTemplateView.php index 345f827d2e..678299df12 100644 --- a/src/view/control/AphrontTokenizerTemplateView.php +++ b/src/view/control/AphrontTokenizerTemplateView.php @@ -1,107 +1,107 @@ <?php final class AphrontTokenizerTemplateView extends AphrontView { private $value; private $name; private $id; public function setID($id) { $this->id = $id; return $this; } public function setValue(array $value) { assert_instances_of($value, 'PhabricatorObjectHandle'); $this->value = $value; return $this; } public function getValue() { return $this->value; } public function setName($name) { $this->name = $name; return $this; } public function getName() { return $this->name; } public function render() { require_celerity_resource('aphront-tokenizer-control-css'); $id = $this->id; $name = $this->getName(); $values = nonempty($this->getValue(), array()); $tokens = array(); foreach ($values as $key => $value) { $tokens[] = $this->renderToken( $value->getPHID(), $value->getFullName(), - $value->getTypeIcon()); + $value->getType()); } $input = javelin_tag( 'input', array( 'mustcapture' => true, 'name' => $name, 'class' => 'jx-tokenizer-input', 'sigil' => 'tokenizer-input', 'style' => 'width: 0px;', 'disabled' => 'disabled', 'type' => 'text', )); $content = $tokens; $content[] = $input; $content[] = phutil_tag('div', array('style' => 'clear: both;'), ''); return phutil_tag( 'div', array( 'id' => $id, 'class' => 'jx-tokenizer-container', ), $content); } private function renderToken($key, $value, $icon) { $input_name = $this->getName(); if ($input_name) { $input_name .= '[]'; } if ($icon) { $value = array( phutil_tag( 'span', array( - 'class' => 'phui-icon-view sprite-status status-'.$icon, + 'class' => 'phui-icon-view phui-font-fa bluegrey '.$icon, )), $value); } return phutil_tag( 'a', array( 'class' => 'jx-tokenizer-token', ), array( $value, phutil_tag( 'input', array( 'type' => 'hidden', 'name' => $input_name, 'value' => $key, )), phutil_tag('span', array('class' => 'jx-tokenizer-x-placeholder'), ''), )); } } diff --git a/src/view/form/control/AphrontFormPolicyControl.php b/src/view/form/control/AphrontFormPolicyControl.php index 31b0798f8b..ee7d8edf1d 100644 --- a/src/view/form/control/AphrontFormPolicyControl.php +++ b/src/view/form/control/AphrontFormPolicyControl.php @@ -1,231 +1,230 @@ <?php final class AphrontFormPolicyControl extends AphrontFormControl { private $object; private $capability; private $policies; public function setPolicyObject(PhabricatorPolicyInterface $object) { $this->object = $object; return $this; } public function setPolicies(array $policies) { assert_instances_of($policies, 'PhabricatorPolicy'); $this->policies = $policies; return $this; } public function setCapability($capability) { $this->capability = $capability; $labels = array( PhabricatorPolicyCapability::CAN_VIEW => pht('Visible To'), PhabricatorPolicyCapability::CAN_EDIT => pht('Editable By'), PhabricatorPolicyCapability::CAN_JOIN => pht('Joinable By'), ); if (isset($labels[$capability])) { $label = $labels[$capability]; } else { $capobj = PhabricatorPolicyCapability::getCapabilityByKey($capability); if ($capobj) { $label = $capobj->getCapabilityName(); } else { $label = pht('Capability "%s"', $capability); } } $this->setLabel($label); return $this; } protected function getCustomControlClass() { return 'aphront-form-control-policy'; } protected function getOptions() { $capability = $this->capability; $options = array(); foreach ($this->policies as $policy) { if ($policy->getPHID() == PhabricatorPolicies::POLICY_PUBLIC) { // Never expose "Public" for capabilities which don't support it. $capobj = PhabricatorPolicyCapability::getCapabilityByKey($capability); if (!$capobj || !$capobj->shouldAllowPublicPolicySetting()) { continue; } } $options[$policy->getType()][$policy->getPHID()] = array( 'name' => phutil_utf8_shorten($policy->getName(), 28), 'full' => $policy->getName(), 'icon' => $policy->getIcon(), ); } // If we were passed several custom policy options, throw away the ones // which aren't the value for this capability. For example, an object might // have a custom view pollicy and a custom edit policy. When we render // the selector for "Can View", we don't want to show the "Can Edit" // custom policy -- if we did, the menu would look like this: // // Custom // Custom Policy // Custom Policy // // ...where one is the "view" custom policy, and one is the "edit" custom // policy. $type_custom = PhabricatorPolicyType::TYPE_CUSTOM; if (!empty($options[$type_custom])) { $options[$type_custom] = array_select_keys( $options[$type_custom], array($this->getValue())); } // If there aren't any custom policies, add a placeholder policy so we // render a menu item. This allows the user to switch to a custom policy. if (empty($options[$type_custom])) { $placeholder = new PhabricatorPolicy(); $placeholder->setName(pht('Custom Policy...')); $options[$type_custom][$this->getCustomPolicyPlaceholder()] = array( 'name' => $placeholder->getName(), 'full' => $placeholder->getName(), 'icon' => $placeholder->getIcon(), ); } $options = array_select_keys( $options, array( PhabricatorPolicyType::TYPE_GLOBAL, PhabricatorPolicyType::TYPE_USER, PhabricatorPolicyType::TYPE_CUSTOM, PhabricatorPolicyType::TYPE_PROJECT, )); return $options; } protected function renderInput() { if (!$this->object) { throw new Exception(pht("Call setPolicyObject() before rendering!")); } if (!$this->capability) { throw new Exception(pht("Call setCapability() before rendering!")); } $policy = $this->object->getPolicy($this->capability); if (!$policy) { // TODO: Make this configurable. $policy = PhabricatorPolicies::POLICY_USER; } if (!$this->getValue()) { $this->setValue($policy); } $control_id = celerity_generate_unique_node_id(); $input_id = celerity_generate_unique_node_id(); $caret = phutil_tag( 'span', array( 'class' => 'caret', )); $input = phutil_tag( 'input', array( 'type' => 'hidden', 'id' => $input_id, 'name' => $this->getName(), 'value' => $this->getValue(), )); $options = $this->getOptions(); $order = array(); $labels = array(); foreach ($options as $key => $values) { $order[$key] = array_keys($values); $labels[$key] = PhabricatorPolicyType::getPolicyTypeName($key); } $flat_options = array_mergev($options); $icons = array(); foreach (igroup($flat_options, 'icon') as $icon => $ignored) { $icons[$icon] = id(new PHUIIconView()) - ->setSpriteSheet(PHUIIconView::SPRITE_STATUS) - ->setSpriteIcon($icon); + ->setIconFont($icon); } Javelin::initBehavior( 'policy-control', array( 'controlID' => $control_id, 'inputID' => $input_id, 'options' => $flat_options, 'groups' => array_keys($options), 'order' => $order, 'icons' => $icons, 'labels' => $labels, 'value' => $this->getValue(), 'customPlaceholder' => $this->getCustomPolicyPlaceholder(), )); $selected = idx($flat_options, $this->getValue(), array()); $selected_icon = idx($selected, 'icon'); $selected_name = idx($selected, 'name'); return phutil_tag( 'div', array( ), array( javelin_tag( 'a', array( 'class' => 'grey button dropdown has-icon policy-control', 'href' => '#', 'mustcapture' => true, 'sigil' => 'policy-control', 'id' => $control_id, ), array( $caret, javelin_tag( 'span', array( 'sigil' => 'policy-label', 'class' => 'phui-button-text', ), array( idx($icons, $selected_icon), $selected_name, )), )), $input, )); return AphrontFormSelectControl::renderSelectTag( $this->getValue(), $this->getOptions(), array( 'name' => $this->getName(), 'disabled' => $this->getDisabled() ? 'disabled' : null, 'id' => $this->getID(), )); } private function getCustomPolicyPlaceholder() { return 'custom:placeholder'; } } diff --git a/src/view/phui/PHUIHeaderView.php b/src/view/phui/PHUIHeaderView.php index 7d69fde223..6844314ea5 100644 --- a/src/view/phui/PHUIHeaderView.php +++ b/src/view/phui/PHUIHeaderView.php @@ -1,275 +1,273 @@ <?php final class PHUIHeaderView extends AphrontView { const PROPERTY_STATUS = 1; private $objectName; private $header; private $tags = array(); private $image; private $imageURL = null; private $subheader; private $gradient; private $noBackground; private $bleedHeader; private $properties = array(); private $actionLinks = array(); private $buttonBar = null; private $policyObject; public function setHeader($header) { $this->header = $header; return $this; } public function setObjectName($object_name) { $this->objectName = $object_name; return $this; } public function setNoBackground($nada) { $this->noBackground = $nada; return $this; } public function addTag(PHUITagView $tag) { $this->tags[] = $tag; return $this; } public function setImage($uri) { $this->image = $uri; return $this; } public function setImageURL($url) { $this->imageURL = $url; return $this; } public function setSubheader($subheader) { $this->subheader = $subheader; return $this; } public function setBleedHeader($bleed) { $this->bleedHeader = $bleed; return $this; } public function setGradient($gradient) { $this->gradient = $gradient; return $this; } public function setPolicyObject(PhabricatorPolicyInterface $object) { $this->policyObject = $object; return $this; } public function addProperty($property, $value) { $this->properties[$property] = $value; return $this; } public function addActionLink(PHUIButtonView $button) { $this->actionLinks[] = $button; return $this; } public function setButtonBar(PHUIButtonBarView $bb) { $this->buttonBar = $bb; return $this; } public function setStatus($icon, $color, $name) { $header_class = 'phui-header-status'; if ($color) { - $icon = $icon.'-'.$color; + $icon = $icon.' '.$color; $header_class = $header_class.'-'.$color; } $img = id(new PHUIIconView()) - ->setSpriteSheet(PHUIIconView::SPRITE_STATUS) - ->setSpriteIcon($icon); + ->setIconFont($icon); $tag = phutil_tag( 'span', array( 'class' => "{$header_class} plr", ), array( $img, $name, )); return $this->addProperty(self::PROPERTY_STATUS, $tag); } public function render() { require_celerity_resource('phui-header-view-css'); $classes = array(); $classes[] = 'phui-header-shell'; if ($this->noBackground) { $classes[] = 'phui-header-no-backgound'; } if ($this->bleedHeader) { $classes[] = 'phui-bleed-header'; } if ($this->gradient) { $classes[] = 'sprite-gradient'; $classes[] = 'gradient-'.$this->gradient.'-header'; } if ($this->properties || $this->policyObject || $this->subheader) { $classes[] = 'phui-header-tall'; } $image = null; if ($this->image) { $image = phutil_tag( ($this->imageURL ? 'a' : 'span'), array( 'href' => $this->imageURL, 'class' => 'phui-header-image', 'style' => 'background-image: url('.$this->image.')', ), ' '); $classes[] = 'phui-header-has-image'; } $header = array(); $header[] = $this->header; if ($this->objectName) { array_unshift( $header, phutil_tag( 'a', array( 'href' => '/'.$this->objectName, ), $this->objectName), ' '); } if ($this->tags) { $header[] = ' '; $header[] = phutil_tag( 'span', array( 'class' => 'phui-header-tags', ), array_interleave(' ', $this->tags)); } if ($this->subheader) { $header[] = phutil_tag( 'div', array( 'class' => 'phui-header-subheader', ), $this->subheader); } if ($this->properties || $this->policyObject) { $property_list = array(); foreach ($this->properties as $type => $property) { switch ($type) { case self::PROPERTY_STATUS: $property_list[] = $property; break; default: throw new Exception('Incorrect Property Passed'); break; } } if ($this->policyObject) { $property_list[] = $this->renderPolicyProperty($this->policyObject); } $header[] = phutil_tag( 'div', array( 'class' => 'phui-header-subheader', ), $property_list); } if ($this->actionLinks) { $actions = array(); foreach ($this->actionLinks as $button) { $button->setColor(PHUIButtonView::SIMPLE); $button->addClass(PHUI::MARGIN_SMALL_LEFT); $button->addClass('phui-header-action-link'); $actions[] = $button; } $header[] = phutil_tag( 'div', array( 'class' => 'phui-header-action-links', ), $actions); } if ($this->buttonBar) { $header[] = phutil_tag( 'div', array( 'class' => 'phui-header-action-links', ), $this->buttonBar); } return phutil_tag( 'div', array( 'class' => implode(' ', $classes), ), array( $image, phutil_tag( 'h1', array( 'class' => 'phui-header-view', ), $header), )); } private function renderPolicyProperty(PhabricatorPolicyInterface $object) { $policies = PhabricatorPolicyQuery::loadPolicies( $this->getUser(), $object); $view_capability = PhabricatorPolicyCapability::CAN_VIEW; $policy = idx($policies, $view_capability); if (!$policy) { return null; } $phid = $object->getPHID(); $icon = id(new PHUIIconView()) - ->setSpriteSheet(PHUIIconView::SPRITE_STATUS) - ->setSpriteIcon($policy->getIcon()); + ->setIconFont($policy->getIcon().' bluegrey'); $link = javelin_tag( 'a', array( 'class' => 'policy-link', 'href' => '/policy/explain/'.$phid.'/'.$view_capability.'/', 'sigil' => 'workflow', ), $policy->getShortName()); return array($icon, $link); } } diff --git a/src/view/phui/PHUIIconView.php b/src/view/phui/PHUIIconView.php index 72c9bb4f13..bac9a363ed 100644 --- a/src/view/phui/PHUIIconView.php +++ b/src/view/phui/PHUIIconView.php @@ -1,117 +1,116 @@ <?php final class PHUIIconView extends AphrontTagView { const SPRITE_MINICONS = 'minicons'; const SPRITE_ACTIONS = 'actions'; const SPRITE_APPS = 'apps'; const SPRITE_TOKENS = 'tokens'; const SPRITE_PAYMENTS = 'payments'; const SPRITE_ICONS = 'icons'; const SPRITE_LOGIN = 'login'; - const SPRITE_STATUS = 'status'; const SPRITE_PROJECTS = 'projects'; const SPRITE_BUTTONBAR = 'buttonbar'; const HEAD_SMALL = 'phuihead-small'; const HEAD_MEDIUM = 'phuihead-medium'; private $href = null; private $image; private $text; private $headSize = null; private $spriteIcon; private $spriteSheet; private $iconFont; public function setHref($href) { $this->href = $href; return $this; } public function setImage($image) { $this->image = $image; return $this; } public function setText($text) { $this->text = $text; return $this; } public function setHeadSize($size) { $this->headSize = $size; return $this; } public function setSpriteIcon($sprite) { $this->spriteIcon = $sprite; return $this; } public function setSpriteSheet($sheet) { $this->spriteSheet = $sheet; return $this; } public function setIconFont($icon) { $this->iconFont = $icon; return $this; } public function getTagName() { $tag = 'span'; if ($this->href) { $tag = 'a'; } return $tag; } public function getTagAttributes() { require_celerity_resource('phui-icon-view-css'); $style = null; $classes = array(); $classes[] = 'phui-icon-view'; if ($this->spriteIcon) { require_celerity_resource('sprite-'.$this->spriteSheet.'-css'); $classes[] = 'sprite-'.$this->spriteSheet; $classes[] = $this->spriteSheet.'-'.$this->spriteIcon; } elseif ($this->iconFont) { require_celerity_resource('phui-font-icon-base-css'); require_celerity_resource('font-fontawesome'); $classes[] = 'phui-font-fa'; $classes[] = $this->iconFont; } else { if ($this->headSize) { $classes[] = $this->headSize; } $style = 'background-image: url('.$this->image.');'; } if ($this->text) { $classes[] = 'phui-icon-has-text'; $this->appendChild($this->text); } return array( 'href' => $this->href, 'style' => $style, 'aural' => false, 'class' => $classes, ); } public static function getSheetManifest($sheet) { $root = dirname(phutil_get_library_root('phabricator')); $path = $root.'/resources/sprite/manifest/'.$sheet.'.json'; $data = Filesystem::readFile($path); return idx(json_decode($data, true), 'sprites'); } } diff --git a/src/view/phui/PHUIPropertyListView.php b/src/view/phui/PHUIPropertyListView.php index 9109173a77..2c5f02dd86 100644 --- a/src/view/phui/PHUIPropertyListView.php +++ b/src/view/phui/PHUIPropertyListView.php @@ -1,246 +1,245 @@ <?php final class PHUIPropertyListView extends AphrontView { private $parts = array(); private $hasKeyboardShortcuts; private $object; private $invokedWillRenderEvent; private $actionList; private $classes = array(); private $stacked; - const ICON_SUMMARY = 'pl-summary'; - const ICON_TESTPLAN = 'pl-testplan'; + const ICON_SUMMARY = 'fa-align-left bluegrey'; + const ICON_TESTPLAN = 'fa-file-text-o bluegrey'; protected function canAppendChild() { return false; } public function setObject($object) { $this->object = $object; return $this; } public function setActionList(PhabricatorActionListView $list) { $this->actionList = $list; return $this; } public function setStacked($stacked) { $this->stacked = $stacked; return $this; } public function addClass($class) { $this->classes[] = $class; return $this; } public function setHasKeyboardShortcuts($has_keyboard_shortcuts) { $this->hasKeyboardShortcuts = $has_keyboard_shortcuts; return $this; } public function addProperty($key, $value) { $current = array_pop($this->parts); if (!$current || $current['type'] != 'property') { if ($current) { $this->parts[] = $current; } $current = array( 'type' => 'property', 'list' => array(), ); } $current['list'][] = array( 'key' => $key, 'value' => $value, ); $this->parts[] = $current; return $this; } public function addSectionHeader($name, $icon=null) { $this->parts[] = array( 'type' => 'section', 'name' => $name, 'icon' => $icon, ); return $this; } public function addTextContent($content) { $this->parts[] = array( 'type' => 'text', 'content' => $content, ); return $this; } public function addImageContent($content) { $this->parts[] = array( 'type' => 'image', 'content' => $content, ); return $this; } public function invokeWillRenderEvent() { if ($this->object && $this->getUser() && !$this->invokedWillRenderEvent) { $event = new PhabricatorEvent( PhabricatorEventType::TYPE_UI_WILLRENDERPROPERTIES, array( 'object' => $this->object, 'view' => $this, )); $event->setUser($this->getUser()); PhutilEventEngine::dispatchEvent($event); } $this->invokedWillRenderEvent = true; } public function render() { $this->invokeWillRenderEvent(); require_celerity_resource('phui-property-list-view-css'); $items = array(); foreach ($this->parts as $part) { $type = $part['type']; switch ($type) { case 'property': $items[] = $this->renderPropertyPart($part); break; case 'section': $items[] = $this->renderSectionPart($part); break; case 'text': case 'image': $items[] = $this->renderTextPart($part); break; default: throw new Exception(pht("Unknown part type '%s'!", $type)); } } $this->classes[] = 'phui-property-list-section'; $classes = implode(' ', $this->classes); return phutil_tag( 'div', array( 'class' => $classes, ), array( $items, )); } private function renderPropertyPart(array $part) { $items = array(); foreach ($part['list'] as $spec) { $key = $spec['key']; $value = $spec['value']; // NOTE: We append a space to each value to improve the behavior when the // user double-clicks a property value (like a URI) to select it. Without // the space, the label is also selected. $items[] = phutil_tag( 'dt', array( 'class' => 'phui-property-list-key', ), array($key, ' ')); $items[] = phutil_tag( 'dd', array( 'class' => 'phui-property-list-value', ), array($value, ' ')); } $stacked = ''; if ($this->stacked) { $stacked = 'phui-property-list-stacked'; } $list = phutil_tag( 'dl', array( 'class' => 'phui-property-list-properties '.$stacked, ), $items); $shortcuts = null; if ($this->hasKeyboardShortcuts) { $shortcuts = new AphrontKeyboardShortcutsAvailableView(); } $list = phutil_tag( 'div', array( 'class' => 'phui-property-list-properties-wrap', ), array($shortcuts, $list)); $action_list = null; if ($this->actionList) { $action_list = phutil_tag( 'div', array( 'class' => 'phui-property-list-actions', ), $this->actionList); $this->actionList = null; } return phutil_tag( 'div', array( 'class' => 'phui-property-list-container grouped', ), array($action_list, $list)); } private function renderSectionPart(array $part) { $name = $part['name']; if ($part['icon']) { $icon = id(new PHUIIconView()) - ->setSpriteSheet(PHUIIconView::SPRITE_STATUS) - ->setSpriteIcon($part['icon']); + ->setIconFont($part['icon']); $name = phutil_tag( 'span', array( 'class' => 'phui-property-list-section-header-icon', ), array($icon, $name)); } return phutil_tag( 'div', array( 'class' => 'phui-property-list-section-header', ), $name); } private function renderTextPart(array $part) { $classes = array(); $classes[] = 'phui-property-list-text-content'; if ($part['type'] == 'image') { $classes[] = 'phui-property-list-image-content'; } return phutil_tag( 'div', array( 'class' => implode($classes, ' '), ), $part['content']); } } diff --git a/webroot/rsrc/css/aphront/typeahead.css b/webroot/rsrc/css/aphront/typeahead.css index 923e2b3fa5..bd889bb571 100644 --- a/webroot/rsrc/css/aphront/typeahead.css +++ b/webroot/rsrc/css/aphront/typeahead.css @@ -1,72 +1,76 @@ /** * @provides aphront-typeahead-control-css */ div.jx-typeahead-hardpoint { position: relative; - _zoom: 1; /* Some kind of IE6 fix? */ /* yes */ + _zoom: 1; /* Some kind of IE6 fix? */ /* yes */ /* why? */ } div.jx-typeahead-results { position: absolute; border: 1px solid #96a6c7; border-top: 0px; padding: 0; background: #fefefe; width: 98%; box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.2); margin: -1px 1% 0; } .aphront-form-control-typeahead div.jx-typeahead-results { width: 100%; margin: 0; box-sizing: border-box; } div.jx-typeahead-results a.jx-result { color: #333; display: block; font-size: 13px; border-bottom: 1px solid #e7e7e7; border-top: 1px solid #fff; } div.jx-typeahead-results a.jx-result:hover, div.jx-typeahead-results a.focused { display: block; - background: #dde6f9; - border-top: 1px solid #dde6f9; - border-bottom: 1px solid #d0dbf3; + background: {$lightblue}; + border-top: 1px solid {$thinblueborder}; + border-bottom: 1px solid {$thinblueborder}; text-decoration: none; } +div.jx-typeahead-results .phui-icon-view { + margin-top: 2px; +} + table.jx-typeahead button { margin-left: 3px; } table.jx-typeahead input { font-size: 13px; padding: 2px; } input.jx-typeahead-placeholder { color: {$lightgreytext}; } div.jx-tokenizer-container-focused.jx-typeahead-waiting { border-color: {$lightblueborder}; } div.jx-typeahead-results a.diffusion-locate-file { padding: 4px 8px; color: {$darkgreytext} } .diffusion-locate-file strong { color: {$blue}; } .diffusion-locate-file .phui-icon-view { padding-right: 8px; } diff --git a/webroot/rsrc/css/phui/phui-header-view.css b/webroot/rsrc/css/phui/phui-header-view.css index 57d213a569..0c08aa9a96 100644 --- a/webroot/rsrc/css/phui/phui-header-view.css +++ b/webroot/rsrc/css/phui/phui-header-view.css @@ -1,133 +1,133 @@ /** * @provides phui-header-view-css */ .phui-header-shell { background-color: #e0e3ec; border-width: 1px 0; border-style: solid; border-color: #c0c5d1; overflow: hidden; } body .phui-header-shell.phui-header-no-backgound { background-color: transparent; border: none; } body .phui-header-shell.phui-bleed-header { background-color: #fff; border-bottom: 1px solid {$thinblueborder}; width: auto; margin: 16px; } body .phui-header-shell.phui-bleed-header .phui-header-view { padding: 8px 24px 8px 0; color: {$bluetext}; } .phui-header-shell + .phabricator-form-view { border-top-width: 0; } .phui-property-list-view + .diviner-document-section { margin-top: -1px; } .phui-header-view { padding: 16px; font-size: 15px; color: {$darkbluetext}; position: relative; } .phui-header-view a, .phui-header-view a.simple { color: {$darkbluetext}; } .phui-header-view .phui-header-action-links { position: absolute; top: 24px; right: 12px; } .phui-object-box .phui-header-view .phui-header-action-links { top: 5px; right: 0; } .phui-document-view .phui-header-view .phui-header-action-links { right: 8px; top: 12px; } .device-phone .phui-header-action-link .phui-button-text { visibility: hidden; width: 0; margin-left: 12px; } .phui-header-divider { margin: 0 4px; font-weight: normal; color: {$lightbluetext}; } body.device-phone .phui-header-view { padding: 12px 8px; } .phui-header-tags { margin-left: 12px; font-size: 13px; } .phui-header-tags .phui-tag-view { margin-left: 4px; } .phui-header-image { display: inline-block; background-repeat: no-repeat; border: 1px solid white; width: 50px; height: 50px; margin: 12px; float: left; } .phui-header-subheader { color: {$lightbluetext}; font-weight: normal; font-size: 13px; margin-top: 4px; } -.phui-header-subheader .sprite-status { +.phui-header-subheader .phui-icon-view { display: inline-block; margin: -2px 4px -2px 0; } .phui-header-subheader { color: {$bluetext}; } .phui-header-subheader .policy-link { color: {$bluetext}; } .phui-header-subheader .phui-header-status-dark { color: #111; text-shadow: 0 1px #fff; } .phui-header-subheader .phui-header-status-red { color: {$red}; } .phui-header-subheader .phui-header-status-green { color: {$green}; } diff --git a/webroot/rsrc/css/phui/phui-icon.css b/webroot/rsrc/css/phui/phui-icon.css index a8c19b5fa5..a18768ce6b 100644 --- a/webroot/rsrc/css/phui/phui-icon.css +++ b/webroot/rsrc/css/phui/phui-icon.css @@ -1,57 +1,56 @@ /** * @provides phui-icon-view-css */ .phui-icon-example .phui-icon-view { display: inline-block; vertical-align: top; } .phui-icon-view.sprite-minicons { height: 16px; width: 16px; } .phui-icon-view.sprite-actions { height: 24px; width: 24px; } .phui-icon-view.sprite-apps, -.phui-icon-view.sprite-status, .phui-icon-view.sprite-buttonbar { height: 14px; width: 14px; } .phui-icon-view.sprite-tokens { height: 16px; width: 16px; display: inline-block; vertical-align: top; } .phui-icon-view.sprite-payments { height: 32px; width: 60px; } .phui-icon-view.sprite-login { height: 34px; width: 34px; } .phui-icon-view.phuihead-medium { height: 50px; width: 50px; } .phui-icon-view.phuihead-small { height: 35px; width: 35px; background-size: 35px; } .phui-icon-has-text:before { margin-right: 8px; } diff --git a/webroot/rsrc/css/phui/phui-property-list-view.css b/webroot/rsrc/css/phui/phui-property-list-view.css index 63dd032a6a..6efcb2f3fb 100644 --- a/webroot/rsrc/css/phui/phui-property-list-view.css +++ b/webroot/rsrc/css/phui/phui-property-list-view.css @@ -1,184 +1,184 @@ /** * @provides phui-property-list-view-css */ .phui-property-list-view { background-color: #fff; } .phui-property-list-view .keyboard-shortcuts-available { float: right; height: 16px; margin: 12px 10px -28px 0px; padding: 0px 20px 0px 0px; vertical-align: middle; color: {$greytext}; text-align: right; font-size: 11px; background: url('/rsrc/image/icon/fatcow/key_question.png') right center no-repeat; } .device .keyboard-shortcuts-available { display: none; } .phui-property-group-noninitial, .phui-property-list-section-noninitial { border-color: {$thinblueborder}; border-style: solid; border-width: 1px 0 0; } .device-desktop .phui-property-list-container { padding: 12px 0 12px 0; width: 100%; } .device .phui-property-list-container { padding: 12px 0 4px 0; } .phui-property-list-key { color: {$bluetext}; font-weight: bold; overflow: hidden; white-space: nowrap; } .device-desktop .phui-property-list-key { width: 18%; margin-left: 1%; text-align: right; float: left; clear: left; margin-bottom: 4px; } .device .phui-property-list-key, .phui-property-list-properties.phui-property-list-stacked .phui-property-list-key { padding-left: 12px; text-align: left; margin-left: 0; width: auto; } .phui-property-list-value { color: {$darkgreytext}; line-height: 17px; } .device-desktop .phui-property-list-value { width: 78%; margin-left: 1%; float: left; margin-bottom: 4px; } .device .phui-property-list-value, .phui-property-list-properties.phui-property-list-stacked .phui-property-list-value { padding: 0 16px; margin-bottom: 8px; width: auto; word-break: break-word; } .phui-property-list-section-header { color: {$bluetext}; padding: 12px 16px 0px; text-transform: uppercase; font-weight: 700; border-color: {$thinblueborder}; border-style: solid; border-width: 1px 0 0; } .phui-property-list-section-noninitial .phui-property-list-section-header { border-top: none; } .device .phui-property-list-section-header { padding-left: 8px; } -.phui-property-list-section-header-icon .sprite-status { +.phui-property-list-section-header-icon .phui-icon-view { display: inline-block; margin: -2px 4px -2px 0; } .phui-property-list-text-content { padding: 12px 16px; background: #fff; overflow: hidden; } .device .phui-property-list-text-content { padding: 8px; } /* In the common case where we immediately follow a header, move back up 30px so we snuggle next to the header. */ .device-desktop .phui-header-view + .phabricator-action-list-view { margin-top: -30px; } .device-desktop .phui-header-view + .phabricator-action-list-view + .phui-property-list-view { margin-top: 0px; } .phui-property-list-image { margin: auto; max-width: 95%; } .phui-property-list-audio { display: block; margin: 16px auto; width: 50%; min-width: 240px; } /* When tags appear in property lists, give them a little more vertical spacing. */ .phui-property-list-view .phui-tag-view { margin: 2px 0; } .phui-property-list-properties-wrap { float: left; width: 78%; } .device .phui-property-list-properties-wrap { width: auto; border: none; } .phui-property-list-actions { width: 20%; float: right; margin-right: 12px; border-left: 1px solid {$thinblueborder}; } .device .phui-property-list-actions { float: none; width: auto; margin: -12px 0 12px 0; } .phui-property-list-image-content img { margin: 20px auto; background: url('/rsrc/image/checker_light.png'); border: 1px solid {$lightblueborder}; } .device-desktop .phui-property-list-image-content img:hover { background: url('/rsrc/image/checker_dark.png'); } diff --git a/webroot/rsrc/css/sprite-status.css b/webroot/rsrc/css/sprite-status.css deleted file mode 100644 index cde9a513f9..0000000000 --- a/webroot/rsrc/css/sprite-status.css +++ /dev/null @@ -1,431 +0,0 @@ -/** - * @provides sprite-status-css - * @generated - */ - -.sprite-status { - background-image: url(/rsrc/image/sprite-status.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-status { - background-image: url(/rsrc/image/sprite-status-X2.png); - background-size: 150px 165px; - } -} - - -.status-accept-blue { - background-position: 0px 0px; -} - -.status-accept-dark { - background-position: -15px 0px; -} - -.status-accept-green { - background-position: -30px 0px; -} - -.status-accept-red { - background-position: -45px 0px; -} - -.status-accept-white { - background-position: -60px 0px; -} - -.status-accept { - background-position: -75px 0px; -} - -.status-add-blue { - background-position: -90px 0px; -} - -.status-add-dark { - background-position: -105px 0px; -} - -.status-add-green { - background-position: -120px 0px; -} - -.status-add-red { - background-position: -135px 0px; -} - -.status-add-white { - background-position: 0px -15px; -} - -.status-add { - background-position: -15px -15px; -} - -.status-down-blue { - background-position: -30px -15px; -} - -.status-down-dark { - background-position: -45px -15px; -} - -.status-down-green { - background-position: -60px -15px; -} - -.status-down-red { - background-position: -75px -15px; -} - -.status-down-white { - background-position: -90px -15px; -} - -.status-down { - background-position: -105px -15px; -} - -.status-info-blue { - background-position: -120px -15px; -} - -.status-info-dark { - background-position: -135px -15px; -} - -.status-info-green { - background-position: 0px -30px; -} - -.status-info-red { - background-position: -15px -30px; -} - -.status-info-white { - background-position: -30px -30px; -} - -.status-info { - background-position: -45px -30px; -} - -.status-left-blue { - background-position: -60px -30px; -} - -.status-left-dark { - background-position: -75px -30px; -} - -.status-left-green { - background-position: -90px -30px; -} - -.status-left-red { - background-position: -105px -30px; -} - -.status-left-white { - background-position: -120px -30px; -} - -.status-left { - background-position: -135px -30px; -} - -.status-minus-blue { - background-position: 0px -45px; -} - -.status-minus-dark { - background-position: -15px -45px; -} - -.status-minus-green { - background-position: -30px -45px; -} - -.status-minus-red { - background-position: -45px -45px; -} - -.status-minus-white { - background-position: -60px -45px; -} - -.status-minus { - background-position: -75px -45px; -} - -.status-oh-closed-dark { - background-position: -90px -45px; -} - -.status-oh-closed { - background-position: -105px -45px; -} - -.status-oh-ok-dark { - background-position: -120px -45px; -} - -.status-oh-ok { - background-position: -135px -45px; -} - -.status-oh-open-green { - background-position: 0px -60px; -} - -.status-oh-open-red { - background-position: -15px -60px; -} - -.status-oh-open { - background-position: -30px -60px; -} - -.status-open-blue { - background-position: -45px -60px; -} - -.status-open-dark { - background-position: -60px -60px; -} - -.status-open-green { - background-position: -75px -60px; -} - -.status-open-red { - background-position: -90px -60px; -} - -.status-open-white { - background-position: -105px -60px; -} - -.status-open { - background-position: -120px -60px; -} - -.status-pl-summary { - background-position: -135px -60px; -} - -.status-pl-testplan { - background-position: 0px -75px; -} - -.status-policy-admin-white, .phuix-dropdown-menu .phabricator-action-view:hover .status-policy-admin { - background-position: -15px -75px; -} - -.status-policy-admin { - background-position: -30px -75px; -} - -.status-policy-all-white, .phuix-dropdown-menu .phabricator-action-view:hover .status-policy-all { - background-position: -45px -75px; -} - -.status-policy-all { - background-position: -60px -75px; -} - -.status-policy-custom-white, .phuix-dropdown-menu .phabricator-action-view:hover .status-policy-custom { - background-position: -75px -75px; -} - -.status-policy-custom { - background-position: -90px -75px; -} - -.status-policy-elist-white { - background-position: -105px -75px; -} - -.status-policy-elist { - background-position: -120px -75px; -} - -.status-policy-noone-white, .phuix-dropdown-menu .phabricator-action-view:hover .status-policy-noone { - background-position: -135px -75px; -} - -.status-policy-noone { - background-position: 0px -90px; -} - -.status-policy-project-white, .phuix-dropdown-menu .phabricator-action-view:hover .status-policy-project { - background-position: -15px -90px; -} - -.status-policy-project { - background-position: -30px -90px; -} - -.status-policy-public-white, .phuix-dropdown-menu .phabricator-action-view:hover .status-policy-public { - background-position: -45px -90px; -} - -.status-policy-public { - background-position: -60px -90px; -} - -.status-policy-unknown-white, .phuix-dropdown-menu .phabricator-action-view:hover .status-policy-unknown { - background-position: -75px -90px; -} - -.status-policy-unknown { - background-position: -90px -90px; -} - -.status-policy-user-white { - background-position: -105px -90px; -} - -.status-policy-user { - background-position: -120px -90px; -} - -.status-question-blue { - background-position: -135px -90px; -} - -.status-question-dark { - background-position: 0px -105px; -} - -.status-question-green { - background-position: -15px -105px; -} - -.status-question-red { - background-position: -30px -105px; -} - -.status-question-white { - background-position: -45px -105px; -} - -.status-question { - background-position: -60px -105px; -} - -.status-reject-blue { - background-position: -75px -105px; -} - -.status-reject-dark { - background-position: -90px -105px; -} - -.status-reject-green { - background-position: -105px -105px; -} - -.status-reject-red { - background-position: -120px -105px; -} - -.status-reject-white { - background-position: -135px -105px; -} - -.status-reject { - background-position: 0px -120px; -} - -.status-right-blue { - background-position: -15px -120px; -} - -.status-right-dark { - background-position: -30px -120px; -} - -.status-right-green { - background-position: -45px -120px; -} - -.status-right-red { - background-position: -60px -120px; -} - -.status-right-white { - background-position: -75px -120px; -} - -.status-right { - background-position: -90px -120px; -} - -.status-time-green { - background-position: -105px -120px; -} - -.status-time-orange { - background-position: -120px -120px; -} - -.status-time-red { - background-position: -135px -120px; -} - -.status-time-yellow { - background-position: 0px -135px; -} - -.status-up-blue { - background-position: -15px -135px; -} - -.status-up-dark { - background-position: -30px -135px; -} - -.status-up-green { - background-position: -45px -135px; -} - -.status-up-red { - background-position: -60px -135px; -} - -.status-up-white { - background-position: -75px -135px; -} - -.status-up { - background-position: -90px -135px; -} - -.status-warning-blue { - background-position: -105px -135px; -} - -.status-warning-dark { - background-position: -120px -135px; -} - -.status-warning-green { - background-position: -135px -135px; -} - -.status-warning-red { - background-position: 0px -150px; -} - -.status-warning-white { - background-position: -15px -150px; -} - -.status-warning { - background-position: -30px -150px; -} diff --git a/webroot/rsrc/image/sprite-status-X2.png b/webroot/rsrc/image/sprite-status-X2.png deleted file mode 100644 index c57de2ef41..0000000000 Binary files a/webroot/rsrc/image/sprite-status-X2.png and /dev/null differ diff --git a/webroot/rsrc/image/sprite-status.png b/webroot/rsrc/image/sprite-status.png deleted file mode 100644 index 5c96fd0c51..0000000000 Binary files a/webroot/rsrc/image/sprite-status.png and /dev/null differ diff --git a/webroot/rsrc/js/application/differential/behavior-dropdown-menus.js b/webroot/rsrc/js/application/differential/behavior-dropdown-menus.js index d8fe6ee0bb..12bd0191a2 100644 --- a/webroot/rsrc/js/application/differential/behavior-dropdown-menus.js +++ b/webroot/rsrc/js/application/differential/behavior-dropdown-menus.js @@ -1,167 +1,169 @@ /** * @provides javelin-behavior-differential-dropdown-menus * @requires javelin-behavior * javelin-dom * javelin-util * javelin-stratcom * phuix-dropdown-menu * phuix-action-list-view * phuix-action-view * phabricator-phtize */ JX.behavior('differential-dropdown-menus', function(config) { var pht = JX.phtize(config.pht); function show_more(container) { var nodes = JX.DOM.scry(container, 'tr', 'context-target'); for (var ii = 0; ii < nodes.length; ii++) { var show = JX.DOM.scry(nodes[ii], 'a', 'show-more'); for (var jj = 0; jj < show.length; jj++) { if (JX.Stratcom.getData(show[jj]).type != 'all') { continue; } var event_data = { context : nodes[ii], show : show[jj] }; JX.Stratcom.invoke('differential-reveal-context', null, event_data); } } } JX.Stratcom.listen( 'click', 'differential-reveal-all', function(e) { var containers = JX.DOM.scry( JX.$('differential-review-stage'), 'div', 'differential-changeset'); for (var i=0; i < containers.length; i++) { show_more(containers[i]); } e.kill(); }); var buildmenu = function(e) { var button = e.getNode('differential-view-options'); var data = JX.Stratcom.getData(button); if (data.menu) { return; } e.prevent(); var menu = new JX.PHUIXDropdownMenu(button); var list = new JX.PHUIXActionListView(); var add_link = function(icon, name, href, local) { if (!href) { return; } var link = new JX.PHUIXActionView() .setIcon(icon) .setName(name) .setHref(href) .setHandler(function(e) { if (local) { window.location.assign(href); } else { window.open(href); } menu.close(); e.prevent(); }); list.addItem(link); return link; }; var reveal_item = new JX.PHUIXActionView() - .setIcon('preview'); + .setIcon('fa-eye'); list.addItem(reveal_item); var visible_item = new JX.PHUIXActionView() .setHandler(function(e) { var diff = JX.DOM.scry( JX.$(data.containerID), 'table', 'differential-diff'); JX.Stratcom.invoke('differential-toggle-file', null, {diff: diff}); e.prevent(); menu.close(); }); list.addItem(visible_item); - add_link('file', pht('Browse in Diffusion'), data.diffusionURI); - add_link('transcript', pht('View Standalone'), data.standaloneURI); - add_link('arrow_left', pht('Show Raw File (Left)'), data.leftURI); - add_link('arrow_right', pht('Show Raw File (Right)'), data.rightURI); - add_link('edit', pht('Open in Editor'), data.editor, true); - add_link('wrench', pht('Configure Editor'), data.editorConfigure); + add_link('fa-files', pht('Browse in Diffusion'), data.diffusionURI); + add_link('fa-file-o', pht('View Standalone'), data.standaloneURI); + add_link('fa-arrow-left', pht('Show Raw File (Left)'), data.leftURI); + add_link('fa-arrow-right', pht('Show Raw File (Right)'), data.rightURI); + add_link('fa-pencil', pht('Open in Editor'), data.editor, true); + add_link('fa-wrench', pht('Configure Editor'), data.editorConfigure); menu.setContent(list.getNode()); menu.listen('open', function() { // When the user opens the menu, check if there are any "Show More" // links in the changeset body. If there aren't, disable the "Show // Entire File" menu item since it won't change anything. var nodes = JX.DOM.scry(JX.$(data.containerID), 'a', 'show-more'); if (nodes.length) { reveal_item .setDisabled(false) .setName(pht('Show Entire File')) + .setIcon('fa-file-o') .setHandler(function(e) { show_more(JX.$(data.containerID)); e.prevent(); menu.close(); }); } else { reveal_item .setDisabled(true) + .setIcon('fa-file') .setName(pht('Entire File Shown')) .setHandler(function(e) { e.prevent(); }); } visible_item.setDisabled(true); visible_item.setName(pht("Can't Toggle Unloaded File")); var diffs = JX.DOM.scry( JX.$(data.containerID), 'table', 'differential-diff'); if (diffs.length > 1) { JX.$E( 'More than one node with sigil "differential-diff" was found in "'+ data.containerID+'."'); } else if (diffs.length == 1) { diff = diffs[0]; visible_item.setDisabled(false); if (JX.Stratcom.getData(diff).hidden) { visible_item .setName(pht('Expand File')) - .setIcon('unmerge'); + .setIcon('fa-expand'); } else { visible_item .setName(pht('Collapse File')) - .setIcon('merge'); + .setIcon('fa-compress'); } } else { // Do nothing when there is no diff shown in the table. For example, // the file is binary. } }); data.menu = menu; menu.open(); }; JX.Stratcom.listen('click', 'differential-view-options', buildmenu); }); diff --git a/webroot/rsrc/js/application/policy/behavior-policy-control.js b/webroot/rsrc/js/application/policy/behavior-policy-control.js index a1c0409df8..e5e0fa4b60 100644 --- a/webroot/rsrc/js/application/policy/behavior-policy-control.js +++ b/webroot/rsrc/js/application/policy/behavior-policy-control.js @@ -1,129 +1,129 @@ /** * @provides javelin-behavior-policy-control * @requires javelin-behavior * javelin-dom * javelin-util * phuix-dropdown-menu * phuix-action-list-view * phuix-action-view * javelin-workflow * @javelin */ JX.behavior('policy-control', function(config) { var control = JX.$(config.controlID); var input = JX.$(config.inputID); var value = config.value; var menu = new JX.PHUIXDropdownMenu(control) .setWidth(260) .setAlign('left'); menu.listen('open', function() { var list = new JX.PHUIXActionListView(); for (var ii = 0; ii < config.groups.length; ii++) { var group = config.groups[ii]; list.addItem( new JX.PHUIXActionView() .setName(config.labels[group]) .setDisabled(true)); for (var jj = 0; jj < config.order[group].length; jj++) { var phid = config.order[group][jj]; var onselect; if (group == 'custom') { onselect = JX.bind(null, function(phid) { var uri = get_custom_uri(phid); new JX.Workflow(uri) .setHandler(function(response) { if (!response.phid) { return; } replace_policy(phid, response.phid, response.info); select_policy(response.phid); }) .start(); }, phid); } else { onselect = JX.bind(null, select_policy, phid); } var option = config.options[phid]; var item = new JX.PHUIXActionView() .setName(option.name) - .setIcon(option.icon, 'status') + .setIcon(option.icon + ' bluegrey') .setHandler(JX.bind(null, function(fn, e) { e.prevent(); menu.close(); fn(); }, onselect)); if (phid == value) { item.setSelected(true); } list.addItem(item); } } menu.setContent(list.getNode()); }); var select_policy = function(phid) { JX.DOM.setContent( JX.DOM.find(control, 'span', 'policy-label'), render_option(phid)); input.value = phid; value = phid; }; var render_option = function(phid, with_title) { var option = config.options[phid]; var name = option.name; if (with_title && (option.full != option.name)) { name = JX.$N('span', {title: option.full}, name); } return [JX.$H(config.icons[option.icon]), name]; }; /** * Get the workflow URI to create or edit a policy with a given PHID. */ var get_custom_uri = function(phid) { var uri = '/policy/edit/'; if (phid != config.customPlaceholder) { uri += phid + '/'; } return uri; }; /** * Replace an existing policy option with a new one. Used to swap out custom * policies after the user edits them. */ var replace_policy = function(old_phid, new_phid, info) { config.options[new_phid] = info; for (var k in config.order) { for (var ii = 0; ii < config.order[k].length; ii++) { if (config.order[k][ii] == old_phid) { config.order[k][ii] = new_phid; return; } } } }; }); diff --git a/webroot/rsrc/js/core/Prefab.js b/webroot/rsrc/js/core/Prefab.js index 5f8142ce45..f4e0bead01 100644 --- a/webroot/rsrc/js/core/Prefab.js +++ b/webroot/rsrc/js/core/Prefab.js @@ -1,269 +1,269 @@ /** * @provides phabricator-prefab * @requires javelin-install * javelin-util * javelin-dom * javelin-typeahead * javelin-tokenizer * javelin-typeahead-preloaded-source * javelin-typeahead-ondemand-source * javelin-dom * javelin-stratcom * javelin-util * @javelin */ /** * Utilities for client-side rendering (the greatest thing in the world). */ JX.install('Prefab', { statics : { renderSelect : function(map, selected, attrs) { var select = JX.$N('select', attrs || {}); for (var k in map) { select.options[select.options.length] = new Option(map[k], k); if (k == selected) { select.value = k; } } select.value = select.value || JX.keys(map)[0]; return select; }, /** * Build a Phabricator tokenizer out of a configuration with application * sorting, datasource and placeholder rules. * * - `id` Root tokenizer ID (alternatively, pass `root`). * - `root` Root tokenizer node (replaces `id`). * - `src` Datasource URI. * - `ondemand` Optional, use an ondemand source. * - `value` Optional, initial value. * - `limit` Optional, token limit. * - `placeholder` Optional, placeholder text. * - `username` Optional, username to sort first (i.e., viewer). * - `icons` Optional, map of icons. * */ buildTokenizer : function(config) { config.icons = config.icons || {}; var root; try { root = config.root || JX.$(config.id); } catch (ex) { // If the root element does not exist, just return without building // anything. This happens in some cases -- like Conpherence -- where we // may load a tokenizer but not put it in the document. return; } var datasource; // Default to an ondemand source if no alternate configuration is // provided. var ondemand = true; if ('ondemand' in config) { ondemand = config.ondemand; } if (ondemand) { datasource = new JX.TypeaheadOnDemandSource(config.src); } else { datasource = new JX.TypeaheadPreloadedSource(config.src); } // Sort results so that the viewing user always comes up first; after // that, prefer unixname matches to realname matches. var sort_handler = function(value, list, cmp) { var priority_hits = {}; var self_hits = {}; var tokens = this.tokenize(value); for (var ii = 0; ii < list.length; ii++) { var item = list[ii]; if (!item.priority) { continue; } if (config.username && item.priority == config.username) { self_hits[item.id] = true; } for (var jj = 0; jj < tokens.length; jj++) { if (item.priority.substr(0, tokens[jj].length) == tokens[jj]) { priority_hits[item.id] = true; } } } list.sort(function(u, v) { if (self_hits[u.id] != self_hits[v.id]) { return self_hits[v.id] ? 1 : -1; } // If one result is open and one is closed, show the open result // first. The "!" tricks here are becaused closed values are display // strings, so the value is either `null` or some truthy string. If // we compare the values directly, we'll apply this rule to two // objects which are both closed but for different reasons, like // "Archived" and "Disabled". var u_open = !u.closed; var v_open = !v.closed; if (u_open != v_open) { if (u_open) { return -1; } else { return 1; } } if (priority_hits[u.id] != priority_hits[v.id]) { return priority_hits[v.id] ? 1 : -1; } // Sort users ahead of other result types. if (u.priorityType != v.priorityType) { if (u.priorityType == 'user') { return -1; } if (v.priorityType == 'user') { return 1; } } return cmp(u, v); }); }; var render_icon = function(icon) { return JX.$N( 'span', - {className: 'phui-icon-view sprite-status status-' + icon}); + {className: 'phui-icon-view phui-font-fa ' + icon}); }; datasource.setSortHandler(JX.bind(datasource, sort_handler)); // Don't show any closed objects until the query is specific enough that // it only selects closed objects. Specifically, if the result list had // any open objects, remove all the closed objects from the list. var filter_handler = function(value, list) { // Look for any open result. var has_open = false; var ii; for (ii = 0; ii < list.length; ii++) { if (!list[ii].closed) { has_open = true; break; } } if (!has_open) { // Everything is closed, so just use it as-is. return list; } // Otherwise, only display the open results. var results = []; for (ii = 0; ii < list.length; ii++) { if (!list[ii].closed) { results.push(list[ii]); } } return results; }; datasource.setFilterHandler(filter_handler); datasource.setTransformer( function(object) { var closed = object[9]; var closed_ui; if (closed) { closed_ui = JX.$N( 'div', {className: 'tokenizer-closed'}, closed); } var icon = object[8]; var icon_ui; if (icon) { icon_ui = render_icon(icon); } var display = JX.$N( 'div', {className: 'tokenizer-result'}, [icon_ui, object[0], closed_ui]); if (closed) { JX.DOM.alterClass(display, 'tokenizer-result-closed', true); } return { name: object[0], display: display, uri: object[1], id: object[2], priority: object[3], priorityType: object[7], icon: icon, closed: closed }; }); var typeahead = new JX.Typeahead( root, JX.DOM.find(root, 'input', 'tokenizer-input')); typeahead.setDatasource(datasource); var tokenizer = new JX.Tokenizer(root); tokenizer.setTypeahead(typeahead); tokenizer.setRenderTokenCallback(function(value, key) { var icon = datasource.getResult(key); if (icon) { icon = icon.icon; } else { icon = config.icons[key]; } if (!icon) { return value; } icon = render_icon(icon); // TODO: Maybe we should render these closed tags in grey? Figure out // how we're going to use color. return [icon, value]; }); if (config.placeholder) { tokenizer.setPlaceholder(config.placeholder); } if (config.limit) { tokenizer.setLimit(config.limit); } if (config.value) { tokenizer.setInitialValue(config.value); } JX.Stratcom.addData(root, {'tokenizer' : tokenizer}); return { tokenizer: tokenizer }; } } }); diff --git a/webroot/rsrc/js/phuix/PHUIXActionView.js b/webroot/rsrc/js/phuix/PHUIXActionView.js index 08ca975404..6fe82c059c 100644 --- a/webroot/rsrc/js/phuix/PHUIXActionView.js +++ b/webroot/rsrc/js/phuix/PHUIXActionView.js @@ -1,151 +1,149 @@ /** * @provides phuix-action-view * @requires javelin-install * javelin-dom * javelin-util * @javelin */ JX.install('PHUIXActionView', { members: { _node: null, _name: null, _icon: 'none', - _iconSheet: 'icons', _disabled: false, _handler: null, _selected: false, _iconNode: null, _nameNode: null, setDisabled: function(disabled) { this._disabled = disabled; JX.DOM.alterClass( this.getNode(), 'phabricator-action-view-disabled', disabled); this._buildIconNode(true); return this; }, setSelected: function(selected) { this._selected = selected; JX.DOM.alterClass( this.getNode(), 'phabricator-action-view-selected', selected); return this; }, setName: function(name) { this._name = name; this._buildNameNode(true); return this; }, setHandler: function(handler) { this._handler = handler; this._buildNameNode(true); return this; }, - setIcon: function(icon, sheet) { + setIcon: function(icon) { this._icon = icon; - this._iconSheet = sheet || this._iconSheet; this._buildIconNode(true); return this; }, setHref: function(href) { this._href = href; this._buildNameNode(true); return this; }, getNode: function() { if (!this._node) { var attr = { className: 'phabricator-action-view' }; var content = [ this._buildIconNode(), this._buildNameNode() ]; this._node = JX.$N('li', attr, content); } return this._node; }, _buildIconNode: function(dirty) { if (!this._iconNode || dirty) { var attr = { className: [ 'phui-icon-view', 'phabricator-action-view-icon', - 'sprite-' + this._iconSheet + 'phui-font-fa' ].join(' ') }; var node = JX.$N('span', attr); - var icon_class = this._iconSheet + '-' + this._icon; + var icon_class = this._icon; if (this._disabled) { - icon_class = icon_class + '-grey'; + icon_class = icon_class + ' grey'; } JX.DOM.alterClass(node, icon_class, true); if (this._iconNode && this._iconNode.parentNode) { JX.DOM.replace(this._iconNode, node); } this._iconNode = node; } return this._iconNode; }, _buildNameNode: function(dirty) { if (!this._nameNode || dirty) { var attr = { className: 'phabricator-action-view-item' }; var href = this._href; if (!href && this._handler) { href = '#'; } if (href) { attr.href = href; } var tag = href ? 'a' : 'span'; var node = JX.$N(tag, attr, this._name); JX.DOM.listen(node, 'click', null, JX.bind(this, this._onclick)); if (this._nameNode && this._nameNode.parentNode) { JX.DOM.replace(this._nameNode, node); } this._nameNode = node; } return this._nameNode; }, _onclick: function(e) { if (this._handler) { this._handler(e); } } } });