diff --git a/resources/sprite/manifest/icon.json b/resources/sprite/manifest/icon.json new file mode 100644 index 0000000000..c12971f2e0 --- /dev/null +++ b/resources/sprite/manifest/icon.json @@ -0,0 +1,196 @@ +{ + "sprites" : [ + "action-arrow_left", + "action-arrow_left-grey", + "action-arrow_left-white", + "action-arrow_right", + "action-arrow_right-grey", + "action-arrow_right-white", + "action-attach", + "action-attach-grey", + "action-attach-white", + "action-blame", + "action-blame-grey", + "action-blame-white", + "action-check", + "action-check-grey", + "action-check-white", + "action-comment", + "action-comment-grey", + "action-comment-white", + "action-computer", + "action-computer-grey", + "action-computer-white", + "action-create", + "action-create-grey", + "action-create-white", + "action-delete", + "action-delete-grey", + "action-delete-white", + "action-disable", + "action-disable-grey", + "action-disable-white", + "action-dislike", + "action-dislike-grey", + "action-dislike-white", + "action-download", + "action-download-grey", + "action-download-white", + "action-edit", + "action-edit-grey", + "action-edit-white", + "action-enable", + "action-enable-grey", + "action-enable-white", + "action-file", + "action-file-grey", + "action-file-white", + "action-flag", + "action-flag-0", + "action-flag-0-grey", + "action-flag-0-white", + "action-flag-1", + "action-flag-1-grey", + "action-flag-1-white", + "action-flag-2", + "action-flag-2-grey", + "action-flag-2-white", + "action-flag-3", + "action-flag-3-grey", + "action-flag-3-white", + "action-flag-4", + "action-flag-4-grey", + "action-flag-4-white", + "action-flag-5", + "action-flag-5-grey", + "action-flag-5-white", + "action-flag-6", + "action-flag-6-grey", + "action-flag-6-white", + "action-flag-7", + "action-flag-7-grey", + "action-flag-7-white", + "action-flag-ghost", + "action-flag-ghost-grey", + "action-flag-ghost-white", + "action-flag-grey", + "action-flag-white", + "action-folder-open", + "action-folder-open-grey", + "action-folder-open-white", + "action-fork", + "action-fork-grey", + "action-fork-white", + "action-herald", + "action-herald-grey", + "action-herald-white", + "action-highlight", + "action-highlight-grey", + "action-highlight-white", + "action-history", + "action-history-grey", + "action-history-white", + "action-image", + "action-image-grey", + "action-image-white", + "action-like", + "action-like-grey", + "action-like-white", + "action-link", + "action-link-grey", + "action-link-white", + "action-lint-info", + "action-lint-info-grey", + "action-lint-info-white", + "action-lint-ok", + "action-lint-ok-grey", + "action-lint-ok-white", + "action-lint-warning", + "action-lint-warning-grey", + "action-lint-warning-white", + "action-lock", + "action-lock-grey", + "action-lock-white", + "action-love", + "action-love-grey", + "action-love-white", + "action-merge", + "action-merge-grey", + "action-merge-white", + "action-message", + "action-message-grey", + "action-message-white", + "action-meta-mta", + "action-meta-mta-grey", + "action-meta-mta-white", + "action-move", + "action-move-grey", + "action-move-white", + "action-new", + "action-new-grey", + "action-new-white", + "action-perflab", + "action-perflab-grey", + "action-perflab-white", + "action-preview", + "action-preview-grey", + "action-preview-white", + "action-refresh", + "action-refresh-grey", + "action-refresh-white", + "action-remove", + "action-remove-grey", + "action-remove-white", + "action-search", + "action-search-grey", + "action-search-white", + "action-start-sandcastle", + "action-start-sandcastle-grey", + "action-start-sandcastle-white", + "action-subscribe-add", + "action-subscribe-add-grey", + "action-subscribe-add-white", + "action-subscribe-auto", + "action-subscribe-auto-grey", + "action-subscribe-auto-white", + "action-subscribe-delete", + "action-subscribe-delete-grey", + "action-subscribe-delete-white", + "action-tag", + "action-tag-grey", + "action-tag-white", + "action-transcript", + "action-transcript-grey", + "action-transcript-white", + "action-undo", + "action-undo-grey", + "action-undo-white", + "action-unlock", + "action-unlock-grey", + "action-unlock-white", + "action-unmerge", + "action-unmerge-grey", + "action-unmerge-white", + "action-unpublish", + "action-unpublish-grey", + "action-unpublish-white", + "action-warning", + "action-warning-grey", + "action-warning-white", + "action-world", + "action-world-grey", + "action-world-white", + "remarkup-assist-text_b", + "remarkup-assist-text_code", + "remarkup-assist-text_help", + "remarkup-assist-text_i", + "remarkup-assist-text_image", + "remarkup-assist-text_larger", + "remarkup-assist-text_meme", + "remarkup-assist-text_ol", + "remarkup-assist-text_table", + "remarkup-assist-text_tag", + "remarkup-assist-text_tt", + "remarkup-assist-text_ul" + ] +} diff --git a/scripts/celerity/generate_sprites.php b/scripts/celerity/generate_sprites.php index 6605c4d2dd..0a101eed4a 100755 --- a/scripts/celerity/generate_sprites.php +++ b/scripts/celerity/generate_sprites.php @@ -27,7 +27,8 @@ if (!$srcroot) { "You must specify a source directory with '--source'."); } -$webroot = dirname(phutil_get_library_root('phabricator')).'/webroot/rsrc'; +$root = dirname(phutil_get_library_root('phabricator')); +$webroot = $root.'/webroot/rsrc'; $webroot = Filesystem::readablePath($webroot); function glx($x) { @@ -192,10 +193,12 @@ $sheet->generateCSS($webroot.'/css/autosprite.css'); $generator = new CeleritySpriteGenerator(); -$icon_sheet = $generator->buildIconSheet(); -$icon_sheet->setScales(array(1, 2)); -$icon_sheet->generateImage($webroot.'/image/sprite-icon.png', 1); -$icon_sheet->generateImage($webroot.'/image/sprite-icon-X2.png', 2); -$icon_sheet->generateCSS($webroot.'/css/sprite-icon.css'); +$generator + ->buildIconSheet() + ->setScales(array(1, 2)) + ->generateImage($webroot.'/image/sprite-icon.png', 1) + ->generateImage($webroot.'/image/sprite-icon-X2.png', 2) + ->generateCSS($webroot.'/css/sprite-icon.css') + ->generateManifest($root.'/resources/sprite/manifest/icon.json'); echo "Done.\n"; diff --git a/scripts/celerity_mapper.php b/scripts/celerity_mapper.php index 72c528f1e0..5febbfee4d 100755 --- a/scripts/celerity_mapper.php +++ b/scripts/celerity_mapper.php @@ -86,6 +86,7 @@ $package_spec = array( 'phabricator-flag-css', 'aphront-error-view-css', 'autosprite-css', + 'sprite-icon-css', 'phabricator-main-menu-view', 'phabricator-notification-css', 'phabricator-notification-menu-css', diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php index e90acfa9d7..2e05e93cce 100644 --- a/src/__celerity_resource_map__.php +++ b/src/__celerity_resource_map__.php @@ -58,8 +58,8 @@ celerity_register_resource_map(array( ), '/rsrc/image/autosprite.png' => array( - 'hash' => 'bc9479b2a610a3ecee18dc88744c4ce6', - 'uri' => '/res/bc9479b2/rsrc/image/autosprite.png', + 'hash' => '0b1fd04e70272fe946dff765237d132a', + 'uri' => '/res/0b1fd04e/rsrc/image/autosprite.png', 'disk' => '/rsrc/image/autosprite.png', 'type' => 'png', ), @@ -539,6 +539,20 @@ celerity_register_resource_map(array( 'disk' => '/rsrc/image/search.png', 'type' => 'png', ), + '/rsrc/image/sprite-icon-X2.png' => + array( + 'hash' => '2ed96382cab2930fb799a39e3f66f4f1', + 'uri' => '/res/2ed96382/rsrc/image/sprite-icon-X2.png', + 'disk' => '/rsrc/image/sprite-icon-X2.png', + 'type' => 'png', + ), + '/rsrc/image/sprite-icon.png' => + array( + 'hash' => '3ad6f08b9770c3150a420d0ab67f6282', + 'uri' => '/res/3ad6f08b/rsrc/image/sprite-icon.png', + 'disk' => '/rsrc/image/sprite-icon.png', + 'type' => 'png', + ), '/rsrc/image/sprite.png' => array( 'hash' => '8c6200d3191c0deea30f22e7b8166b15', @@ -727,7 +741,7 @@ celerity_register_resource_map(array( ), 'autosprite-css' => array( - 'uri' => '/res/6be3e4b3/rsrc/css/autosprite.css', + 'uri' => '/res/e1084d7c/rsrc/css/autosprite.css', 'type' => 'css', 'requires' => array( @@ -2367,7 +2381,7 @@ celerity_register_resource_map(array( ), 'phabricator-action-list-view-css' => array( - 'uri' => '/res/05a6dbac/rsrc/css/layout/phabricator-action-list-view.css', + 'uri' => '/res/a5a123d0/rsrc/css/layout/phabricator-action-list-view.css', 'type' => 'css', 'requires' => array( @@ -3085,6 +3099,15 @@ celerity_register_resource_map(array( ), 'disk' => '/rsrc/js/raphael/g.raphael.line.js', ), + 'sprite-icon-css' => + array( + 'uri' => '/res/ca19186e/rsrc/css/sprite-icon.css', + 'type' => 'css', + 'requires' => + array( + ), + 'disk' => '/rsrc/css/sprite-icon.css', + ), 'stripe-core' => array( 'uri' => '/res/3b0f0ad4/rsrc/js/stripe/stripe_core.js', @@ -3115,7 +3138,7 @@ celerity_register_resource_map(array( ), array( 'packages' => array( - '8f8908d2' => + '5c5dd816' => array( 'name' => 'core.pkg.css', 'symbols' => @@ -3144,16 +3167,17 @@ celerity_register_resource_map(array( 21 => 'phabricator-flag-css', 22 => 'aphront-error-view-css', 23 => 'autosprite-css', - 24 => 'phabricator-main-menu-view', - 25 => 'phabricator-notification-css', - 26 => 'phabricator-notification-menu-css', - 27 => 'lightbox-attachment-css', - 28 => 'phabricator-header-view-css', - 29 => 'phabricator-form-view-css', - 30 => 'phabricator-filetree-view-css', - 31 => 'phabricator-nav-view-css', + 24 => 'sprite-icon-css', + 25 => 'phabricator-main-menu-view', + 26 => 'phabricator-notification-css', + 27 => 'phabricator-notification-menu-css', + 28 => 'lightbox-attachment-css', + 29 => 'phabricator-header-view-css', + 30 => 'phabricator-form-view-css', + 31 => 'phabricator-filetree-view-css', + 32 => 'phabricator-nav-view-css', ), - 'uri' => '/res/pkg/8f8908d2/core.pkg.css', + 'uri' => '/res/pkg/5c5dd816/core.pkg.css', 'type' => 'css', ), 'd223b82c' => @@ -3343,21 +3367,21 @@ celerity_register_resource_map(array( 'reverse' => array( 'aphront-attached-file-view-css' => '7839ae2d', - 'aphront-crumbs-view-css' => '8f8908d2', - 'aphront-dialog-view-css' => '8f8908d2', - 'aphront-error-view-css' => '8f8908d2', - 'aphront-form-view-css' => '8f8908d2', + 'aphront-crumbs-view-css' => '5c5dd816', + 'aphront-dialog-view-css' => '5c5dd816', + 'aphront-error-view-css' => '5c5dd816', + 'aphront-form-view-css' => '5c5dd816', 'aphront-headsup-action-list-view-css' => '47549184', - 'aphront-headsup-view-css' => '8f8908d2', - 'aphront-list-filter-view-css' => '8f8908d2', - 'aphront-pager-view-css' => '8f8908d2', - 'aphront-panel-view-css' => '8f8908d2', - 'aphront-side-nav-view-css' => '8f8908d2', - 'aphront-table-view-css' => '8f8908d2', - 'aphront-tokenizer-control-css' => '8f8908d2', - 'aphront-tooltip-css' => '8f8908d2', - 'aphront-typeahead-control-css' => '8f8908d2', - 'autosprite-css' => '8f8908d2', + 'aphront-headsup-view-css' => '5c5dd816', + 'aphront-list-filter-view-css' => '5c5dd816', + 'aphront-pager-view-css' => '5c5dd816', + 'aphront-panel-view-css' => '5c5dd816', + 'aphront-side-nav-view-css' => '5c5dd816', + 'aphront-table-view-css' => '5c5dd816', + 'aphront-tokenizer-control-css' => '5c5dd816', + 'aphront-tooltip-css' => '5c5dd816', + 'aphront-typeahead-control-css' => '5c5dd816', + 'autosprite-css' => '5c5dd816', 'differential-changeset-view-css' => '47549184', 'differential-core-view-css' => '47549184', 'differential-inline-comment-editor' => '7ecd31fa', @@ -3440,41 +3464,42 @@ celerity_register_resource_map(array( 'javelin-util' => '20727878', 'javelin-vector' => '20727878', 'javelin-workflow' => '20727878', - 'lightbox-attachment-css' => '8f8908d2', + 'lightbox-attachment-css' => '5c5dd816', 'maniphest-task-summary-css' => '7839ae2d', 'maniphest-transaction-detail-css' => '7839ae2d', - 'phabricator-app-buttons-css' => '8f8908d2', + 'phabricator-app-buttons-css' => '5c5dd816', 'phabricator-busy' => 'd223b82c', 'phabricator-content-source-view-css' => '47549184', - 'phabricator-core-buttons-css' => '8f8908d2', - 'phabricator-core-css' => '8f8908d2', - 'phabricator-directory-css' => '8f8908d2', + 'phabricator-core-buttons-css' => '5c5dd816', + 'phabricator-core-css' => '5c5dd816', + 'phabricator-directory-css' => '5c5dd816', 'phabricator-drag-and-drop-file-upload' => '7ecd31fa', 'phabricator-dropdown-menu' => 'd223b82c', 'phabricator-file-upload' => 'd223b82c', - 'phabricator-filetree-view-css' => '8f8908d2', - 'phabricator-flag-css' => '8f8908d2', - 'phabricator-form-view-css' => '8f8908d2', - 'phabricator-header-view-css' => '8f8908d2', - 'phabricator-jump-nav' => '8f8908d2', + 'phabricator-filetree-view-css' => '5c5dd816', + 'phabricator-flag-css' => '5c5dd816', + 'phabricator-form-view-css' => '5c5dd816', + 'phabricator-header-view-css' => '5c5dd816', + 'phabricator-jump-nav' => '5c5dd816', 'phabricator-keyboard-shortcut' => 'd223b82c', 'phabricator-keyboard-shortcut-manager' => 'd223b82c', - 'phabricator-main-menu-view' => '8f8908d2', + 'phabricator-main-menu-view' => '5c5dd816', 'phabricator-menu-item' => 'd223b82c', - 'phabricator-nav-view-css' => '8f8908d2', + 'phabricator-nav-view-css' => '5c5dd816', 'phabricator-notification' => 'd223b82c', - 'phabricator-notification-css' => '8f8908d2', - 'phabricator-notification-menu-css' => '8f8908d2', + 'phabricator-notification-css' => '5c5dd816', + 'phabricator-notification-menu-css' => '5c5dd816', 'phabricator-object-selector-css' => '47549184', 'phabricator-paste-file-upload' => 'd223b82c', 'phabricator-prefab' => 'd223b82c', 'phabricator-project-tag-css' => '7839ae2d', - 'phabricator-remarkup-css' => '8f8908d2', + 'phabricator-remarkup-css' => '5c5dd816', 'phabricator-shaped-request' => '7ecd31fa', - 'phabricator-standard-page-view' => '8f8908d2', + 'phabricator-standard-page-view' => '5c5dd816', 'phabricator-textareautils' => 'd223b82c', 'phabricator-tooltip' => 'd223b82c', - 'phabricator-transaction-view-css' => '8f8908d2', - 'syntax-highlighting-css' => '8f8908d2', + 'phabricator-transaction-view-css' => '5c5dd816', + 'sprite-icon-css' => '5c5dd816', + 'syntax-highlighting-css' => '5c5dd816', ), )); diff --git a/src/applications/uiexample/examples/PhabricatorActionListExample.php b/src/applications/uiexample/examples/PhabricatorActionListExample.php index 2922d95cee..44f6e01791 100644 --- a/src/applications/uiexample/examples/PhabricatorActionListExample.php +++ b/src/applications/uiexample/examples/PhabricatorActionListExample.php @@ -97,7 +97,6 @@ final class PhabricatorActionListExample extends PhabricatorUIExample { id(new PhabricatorActionView()) ->setUser($user) ->setHref('#') - ->setDisabled(true) ->setName('Icon "'.$icon.'"') ->setIcon($icon)); } diff --git a/src/infrastructure/celerity/CeleritySpriteGenerator.php b/src/infrastructure/celerity/CeleritySpriteGenerator.php new file mode 100644 index 0000000000..febd36f653 --- /dev/null +++ b/src/infrastructure/celerity/CeleritySpriteGenerator.php @@ -0,0 +1,132 @@ +getDirectoryList('icons_1x'); + + $colors = array( + '', + 'grey', + 'white', + ); + + $scales = array( + '1x' => 1, + '2x' => 2, + ); + + $template = id(new PhutilSprite()) + ->setSourceSize(14, 14); + + $sprites = array(); + foreach ($colors as $color) { + foreach ($icons as $icon) { + $prefix = 'icons_'; + if (strlen($color)) { + $prefix .= $color.'_'; + } + + $suffix = ''; + if (strlen($color)) { + $suffix = '-'.$color; + } + + $sprite = id(clone $template) + ->setName('action-'.$icon.$suffix); + + if ($color == 'white') { + $sprite->setTargetCSS( + '.device-desktop .phabricator-action-view:hover .action-'.$icon); + } else { + $sprite->setTargetCSS('.action-'.$icon.$suffix); + } + + foreach ($scales as $scale_key => $scale) { + $path = $this->getPath($prefix.$scale_key.'/'.$icon.'.png'); + $sprite->setSourceFile($path, $scale); + } + $sprites[] = $sprite; + } + } + + $remarkup_icons = $this->getDirectoryList('remarkup_1x'); + foreach ($remarkup_icons as $icon) { + $prefix = 'remarkup_'; + + // Strip 'text_' from these file names. + $class_name = substr($icon, 5); + + $sprite = id(clone $template) + ->setName('remarkup-assist-'.$icon) + ->setTargetCSS('.remarkup-assist-'.$class_name); + foreach ($scales as $scale_key => $scale) { + $path = $this->getPath($prefix.$scale_key.'/'.$icon.'.png'); + $sprite->setSourceFile($path, $scale); + } + $sprites[] = $sprite; + } + + $sheet = $this->buildSheet('icon'); + $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) { + $sheet = new PhutilSpriteSheet(); + + $at = '@'; + $sheet->setCSSHeader(<< 'remarkup-assist autosprite remarkup-assist-'.$action, + 'class' => 'remarkup-assist sprite-icon remarkup-assist-'.$action, ), '')); } diff --git a/src/view/layout/PhabricatorActionView.php b/src/view/layout/PhabricatorActionView.php index 0bdae18153..10f3a49115 100644 --- a/src/view/layout/PhabricatorActionView.php +++ b/src/view/layout/PhabricatorActionView.php @@ -49,11 +49,18 @@ final class PhabricatorActionView extends AphrontView { $icon = null; if ($this->icon) { + + $suffix = ''; + if ($this->disabled) { + $suffix = '-grey'; + } + + require_celerity_resource('sprite-icon-css'); $icon = phutil_render_tag( 'span', array( - 'class' => 'phabricator-action-view-icon autosprite '. - 'action-'.$this->icon, + 'class' => 'phabricator-action-view-icon sprite-icon '. + 'action-'.$this->icon.$suffix, ), ''); } @@ -114,32 +121,23 @@ final class PhabricatorActionView extends AphrontView { } public static function getAvailableIcons() { - return array( - 'delete', - 'download', - 'edit', - 'file', - 'flag-0', - 'flag-1', - 'flag-2', - 'flag-3', - 'flag-4', - 'flag-5', - 'flag-6', - 'flag-7', - 'flag-ghost', - 'fork', - 'move', - 'new', - 'preview', - 'subscribe-add', - 'subscribe-auto', - 'subscribe-delete', - 'undo', - 'unlock', - 'unpublish', - 'world', - ); + $root = dirname(phutil_get_library_root('phabricator')); + $path = $root.'/resources/sprite/manifest/icon.json'; + $data = Filesystem::readFile($path); + $manifest = json_decode($data, true); + + $results = array(); + $prefix = 'action-'; + foreach ($manifest['sprites'] as $sprite) { + if (preg_match('/-(white|grey)$/', $sprite)) { + continue; + } + if (!strncmp($sprite, $prefix, strlen($prefix))) { + $results[] = substr($sprite, strlen($prefix)); + } + } + + return $results; } } diff --git a/webroot/rsrc/css/layout/phabricator-action-list-view.css b/webroot/rsrc/css/layout/phabricator-action-list-view.css index a89e719454..8a2d0e55f6 100644 --- a/webroot/rsrc/css/layout/phabricator-action-list-view.css +++ b/webroot/rsrc/css/layout/phabricator-action-list-view.css @@ -28,7 +28,7 @@ } .phabricator-action-view { - padding: 2px 0; + padding: 1px 0; position: relative; } @@ -37,7 +37,6 @@ background: transparent; box-shadow: none; outline: 0; - box-shadow: 0; padding: 0; margin: 0; font-weight: normal; @@ -45,28 +44,35 @@ width: 100%; text-align: left; text-shadow: none; + + border-radius: 0; + color: #18559D; + font: inherit; + display: inline; + min-width: 0; } .phabricator-action-view button.phabricator-action-view-item, .phabricator-action-view-item { + padding: 1px 0 1px 34px; line-height: 20px; - padding-left: 34px; display: block; font-size: 12px; + text-decoration: none; } .phabricator-action-view-icon { - width: 16px; - height: 16px; + width: 14px; + height: 14px; position: absolute; - top: 4px; - left: 12px; + top: 5px; + left: 13px; } -.device-desktop .phabricator-action-view-item:hover { +.device-desktop .phabricator-action-view:hover .phabricator-action-view-item { + text-decoration: none; background-color: #3875d7; color: #ffffff; - text-decoration: none; } .phabricator-action-view-disabled .phabricator-action-view-item, @@ -74,8 +80,10 @@ color: #888888; } -.phabricator-action-view-disabled .phabricator-action-view-item:hover, -.phabricator-action-view-disabled button.phabricator-action-view-item:hover { +.device-desktop .phabricator-action-view-disabled:hover + .phabricator-action-view-item, +.device-desktop .phabricator-action-view-disabled:hover + button.phabricator-action-view-item { background-color: #dfdfdf; color: #888888; } diff --git a/webroot/rsrc/css/sprite-icon.css b/webroot/rsrc/css/sprite-icon.css new file mode 100644 index 0000000000..e60a243b07 --- /dev/null +++ b/webroot/rsrc/css/sprite-icon.css @@ -0,0 +1,786 @@ +/** + * @provides sprite-icon-css + * @generated + */ + +.sprite-icon { + background-image: url(/rsrc/image/sprite-icon.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-icon { + background-image: url(/rsrc/image/sprite-icon-X2.png); + background-size: 210px 210px; + } +} + +.action-arrow_left { + background-position: 0px 0px; +} + +.action-arrow_right { + background-position: -15px 0px; +} + +.action-attach { + background-position: -30px 0px; +} + +.action-blame { + background-position: -45px 0px; +} + +.action-check { + background-position: -60px 0px; +} + +.action-comment { + background-position: -75px 0px; +} + +.action-computer { + background-position: -90px 0px; +} + +.action-create { + background-position: -105px 0px; +} + +.action-delete { + background-position: -120px 0px; +} + +.action-disable { + background-position: -135px 0px; +} + +.action-dislike { + background-position: -150px 0px; +} + +.action-download { + background-position: -165px 0px; +} + +.action-edit { + background-position: -180px 0px; +} + +.action-enable { + background-position: -195px 0px; +} + +.action-file { + background-position: 0px -15px; +} + +.action-flag-0 { + background-position: -15px -15px; +} + +.action-flag-1 { + background-position: -30px -15px; +} + +.action-flag-2 { + background-position: -45px -15px; +} + +.action-flag-3 { + background-position: -60px -15px; +} + +.action-flag-4 { + background-position: -75px -15px; +} + +.action-flag-5 { + background-position: -90px -15px; +} + +.action-flag-6 { + background-position: -105px -15px; +} + +.action-flag-7 { + background-position: -120px -15px; +} + +.action-flag-ghost { + background-position: -135px -15px; +} + +.action-flag { + background-position: -150px -15px; +} + +.action-folder-open { + background-position: -165px -15px; +} + +.action-fork { + background-position: -180px -15px; +} + +.action-herald { + background-position: -195px -15px; +} + +.action-highlight { + background-position: 0px -30px; +} + +.action-history { + background-position: -15px -30px; +} + +.action-image { + background-position: -30px -30px; +} + +.action-like { + background-position: -45px -30px; +} + +.action-link { + background-position: -60px -30px; +} + +.action-lint-info { + background-position: -75px -30px; +} + +.action-lint-ok { + background-position: -90px -30px; +} + +.action-lint-warning { + background-position: -105px -30px; +} + +.action-lock { + background-position: -120px -30px; +} + +.action-love { + background-position: -135px -30px; +} + +.action-merge { + background-position: -150px -30px; +} + +.action-message { + background-position: -165px -30px; +} + +.action-meta-mta { + background-position: -180px -30px; +} + +.action-move { + background-position: -195px -30px; +} + +.action-new { + background-position: 0px -45px; +} + +.action-perflab { + background-position: -15px -45px; +} + +.action-preview { + background-position: -30px -45px; +} + +.action-refresh { + background-position: -45px -45px; +} + +.action-remove { + background-position: -60px -45px; +} + +.action-search { + background-position: -75px -45px; +} + +.action-start-sandcastle { + background-position: -90px -45px; +} + +.action-subscribe-add { + background-position: -105px -45px; +} + +.action-subscribe-auto { + background-position: -120px -45px; +} + +.action-subscribe-delete { + background-position: -135px -45px; +} + +.action-tag { + background-position: -150px -45px; +} + +.action-transcript { + background-position: -165px -45px; +} + +.action-undo { + background-position: -180px -45px; +} + +.action-unlock { + background-position: -195px -45px; +} + +.action-unmerge { + background-position: 0px -60px; +} + +.action-unpublish { + background-position: -15px -60px; +} + +.action-warning { + background-position: -30px -60px; +} + +.action-world { + background-position: -45px -60px; +} + +.action-arrow_left-grey { + background-position: -60px -60px; +} + +.action-arrow_right-grey { + background-position: -75px -60px; +} + +.action-attach-grey { + background-position: -90px -60px; +} + +.action-blame-grey { + background-position: -105px -60px; +} + +.action-check-grey { + background-position: -120px -60px; +} + +.action-comment-grey { + background-position: -135px -60px; +} + +.action-computer-grey { + background-position: -150px -60px; +} + +.action-create-grey { + background-position: -165px -60px; +} + +.action-delete-grey { + background-position: -180px -60px; +} + +.action-disable-grey { + background-position: -195px -60px; +} + +.action-dislike-grey { + background-position: 0px -75px; +} + +.action-download-grey { + background-position: -15px -75px; +} + +.action-edit-grey { + background-position: -30px -75px; +} + +.action-enable-grey { + background-position: -45px -75px; +} + +.action-file-grey { + background-position: -60px -75px; +} + +.action-flag-0-grey { + background-position: -75px -75px; +} + +.action-flag-1-grey { + background-position: -90px -75px; +} + +.action-flag-2-grey { + background-position: -105px -75px; +} + +.action-flag-3-grey { + background-position: -120px -75px; +} + +.action-flag-4-grey { + background-position: -135px -75px; +} + +.action-flag-5-grey { + background-position: -150px -75px; +} + +.action-flag-6-grey { + background-position: -165px -75px; +} + +.action-flag-7-grey { + background-position: -180px -75px; +} + +.action-flag-ghost-grey { + background-position: -195px -75px; +} + +.action-flag-grey { + background-position: 0px -90px; +} + +.action-folder-open-grey { + background-position: -15px -90px; +} + +.action-fork-grey { + background-position: -30px -90px; +} + +.action-herald-grey { + background-position: -45px -90px; +} + +.action-highlight-grey { + background-position: -60px -90px; +} + +.action-history-grey { + background-position: -75px -90px; +} + +.action-image-grey { + background-position: -90px -90px; +} + +.action-like-grey { + background-position: -105px -90px; +} + +.action-link-grey { + background-position: -120px -90px; +} + +.action-lint-info-grey { + background-position: -135px -90px; +} + +.action-lint-ok-grey { + background-position: -150px -90px; +} + +.action-lint-warning-grey { + background-position: -165px -90px; +} + +.action-lock-grey { + background-position: -180px -90px; +} + +.action-love-grey { + background-position: -195px -90px; +} + +.action-merge-grey { + background-position: 0px -105px; +} + +.action-message-grey { + background-position: -15px -105px; +} + +.action-meta-mta-grey { + background-position: -30px -105px; +} + +.action-move-grey { + background-position: -45px -105px; +} + +.action-new-grey { + background-position: -60px -105px; +} + +.action-perflab-grey { + background-position: -75px -105px; +} + +.action-preview-grey { + background-position: -90px -105px; +} + +.action-refresh-grey { + background-position: -105px -105px; +} + +.action-remove-grey { + background-position: -120px -105px; +} + +.action-search-grey { + background-position: -135px -105px; +} + +.action-start-sandcastle-grey { + background-position: -150px -105px; +} + +.action-subscribe-add-grey { + background-position: -165px -105px; +} + +.action-subscribe-auto-grey { + background-position: -180px -105px; +} + +.action-subscribe-delete-grey { + background-position: -195px -105px; +} + +.action-tag-grey { + background-position: 0px -120px; +} + +.action-transcript-grey { + background-position: -15px -120px; +} + +.action-undo-grey { + background-position: -30px -120px; +} + +.action-unlock-grey { + background-position: -45px -120px; +} + +.action-unmerge-grey { + background-position: -60px -120px; +} + +.action-unpublish-grey { + background-position: -75px -120px; +} + +.action-warning-grey { + background-position: -90px -120px; +} + +.action-world-grey { + background-position: -105px -120px; +} + +.device-desktop .phabricator-action-view:hover .action-arrow_left { + background-position: -120px -120px; +} + +.device-desktop .phabricator-action-view:hover .action-arrow_right { + background-position: -135px -120px; +} + +.device-desktop .phabricator-action-view:hover .action-attach { + background-position: -150px -120px; +} + +.device-desktop .phabricator-action-view:hover .action-blame { + background-position: -165px -120px; +} + +.device-desktop .phabricator-action-view:hover .action-check { + background-position: -180px -120px; +} + +.device-desktop .phabricator-action-view:hover .action-comment { + background-position: -195px -120px; +} + +.device-desktop .phabricator-action-view:hover .action-computer { + background-position: 0px -135px; +} + +.device-desktop .phabricator-action-view:hover .action-create { + background-position: -15px -135px; +} + +.device-desktop .phabricator-action-view:hover .action-delete { + background-position: -30px -135px; +} + +.device-desktop .phabricator-action-view:hover .action-disable { + background-position: -45px -135px; +} + +.device-desktop .phabricator-action-view:hover .action-dislike { + background-position: -60px -135px; +} + +.device-desktop .phabricator-action-view:hover .action-download { + background-position: -75px -135px; +} + +.device-desktop .phabricator-action-view:hover .action-edit { + background-position: -90px -135px; +} + +.device-desktop .phabricator-action-view:hover .action-enable { + background-position: -105px -135px; +} + +.device-desktop .phabricator-action-view:hover .action-file { + background-position: -120px -135px; +} + +.device-desktop .phabricator-action-view:hover .action-flag-0 { + background-position: -135px -135px; +} + +.device-desktop .phabricator-action-view:hover .action-flag-1 { + background-position: -150px -135px; +} + +.device-desktop .phabricator-action-view:hover .action-flag-2 { + background-position: -165px -135px; +} + +.device-desktop .phabricator-action-view:hover .action-flag-3 { + background-position: -180px -135px; +} + +.device-desktop .phabricator-action-view:hover .action-flag-4 { + background-position: -195px -135px; +} + +.device-desktop .phabricator-action-view:hover .action-flag-5 { + background-position: 0px -150px; +} + +.device-desktop .phabricator-action-view:hover .action-flag-6 { + background-position: -15px -150px; +} + +.device-desktop .phabricator-action-view:hover .action-flag-7 { + background-position: -30px -150px; +} + +.device-desktop .phabricator-action-view:hover .action-flag-ghost { + background-position: -45px -150px; +} + +.device-desktop .phabricator-action-view:hover .action-flag { + background-position: -60px -150px; +} + +.device-desktop .phabricator-action-view:hover .action-folder-open { + background-position: -75px -150px; +} + +.device-desktop .phabricator-action-view:hover .action-fork { + background-position: -90px -150px; +} + +.device-desktop .phabricator-action-view:hover .action-herald { + background-position: -105px -150px; +} + +.device-desktop .phabricator-action-view:hover .action-highlight { + background-position: -120px -150px; +} + +.device-desktop .phabricator-action-view:hover .action-history { + background-position: -135px -150px; +} + +.device-desktop .phabricator-action-view:hover .action-image { + background-position: -150px -150px; +} + +.device-desktop .phabricator-action-view:hover .action-like { + background-position: -165px -150px; +} + +.device-desktop .phabricator-action-view:hover .action-link { + background-position: -180px -150px; +} + +.device-desktop .phabricator-action-view:hover .action-lint-info { + background-position: 0px -165px; +} + +.device-desktop .phabricator-action-view:hover .action-lint-ok { + background-position: -15px -165px; +} + +.device-desktop .phabricator-action-view:hover .action-lint-warning { + background-position: -30px -165px; +} + +.device-desktop .phabricator-action-view:hover .action-lock { + background-position: -45px -165px; +} + +.device-desktop .phabricator-action-view:hover .action-love { + background-position: -60px -165px; +} + +.device-desktop .phabricator-action-view:hover .action-merge { + background-position: -75px -165px; +} + +.device-desktop .phabricator-action-view:hover .action-message { + background-position: -90px -165px; +} + +.device-desktop .phabricator-action-view:hover .action-meta-mta { + background-position: -105px -165px; +} + +.device-desktop .phabricator-action-view:hover .action-move { + background-position: -120px -165px; +} + +.device-desktop .phabricator-action-view:hover .action-new { + background-position: -135px -165px; +} + +.device-desktop .phabricator-action-view:hover .action-perflab { + background-position: -150px -165px; +} + +.device-desktop .phabricator-action-view:hover .action-preview { + background-position: -165px -165px; +} + +.device-desktop .phabricator-action-view:hover .action-refresh { + background-position: -180px -165px; +} + +.device-desktop .phabricator-action-view:hover .action-remove { + background-position: 0px -180px; +} + +.device-desktop .phabricator-action-view:hover .action-search { + background-position: -15px -180px; +} + +.device-desktop .phabricator-action-view:hover .action-start-sandcastle { + background-position: -30px -180px; +} + +.device-desktop .phabricator-action-view:hover .action-subscribe-add { + background-position: -45px -180px; +} + +.device-desktop .phabricator-action-view:hover .action-subscribe-auto { + background-position: -60px -180px; +} + +.device-desktop .phabricator-action-view:hover .action-subscribe-delete { + background-position: -75px -180px; +} + +.device-desktop .phabricator-action-view:hover .action-tag { + background-position: -90px -180px; +} + +.device-desktop .phabricator-action-view:hover .action-transcript { + background-position: -105px -180px; +} + +.device-desktop .phabricator-action-view:hover .action-undo { + background-position: -120px -180px; +} + +.device-desktop .phabricator-action-view:hover .action-unlock { + background-position: -135px -180px; +} + +.device-desktop .phabricator-action-view:hover .action-unmerge { + background-position: -150px -180px; +} + +.device-desktop .phabricator-action-view:hover .action-unpublish { + background-position: -165px -180px; +} + +.device-desktop .phabricator-action-view:hover .action-warning { + background-position: -180px -180px; +} + +.device-desktop .phabricator-action-view:hover .action-world { + background-position: 0px -195px; +} + +.remarkup-assist-b { + background-position: -15px -195px; +} + +.remarkup-assist-code { + background-position: -30px -195px; +} + +.remarkup-assist-help { + background-position: -45px -195px; +} + +.remarkup-assist-i { + background-position: -60px -195px; +} + +.remarkup-assist-image { + background-position: -75px -195px; +} + +.remarkup-assist-larger { + background-position: -90px -195px; +} + +.remarkup-assist-meme { + background-position: -105px -195px; +} + +.remarkup-assist-ol { + background-position: -120px -195px; +} + +.remarkup-assist-table { + background-position: -135px -195px; +} + +.remarkup-assist-tag { + background-position: -150px -195px; +} + +.remarkup-assist-tt { + background-position: -165px -195px; +} + +.remarkup-assist-ul { + background-position: -180px -195px; +} diff --git a/webroot/rsrc/image/autosprite.png b/webroot/rsrc/image/autosprite.png index 1bab2a4e1d..98e0dc238f 100644 Binary files a/webroot/rsrc/image/autosprite.png and b/webroot/rsrc/image/autosprite.png differ diff --git a/webroot/rsrc/image/sprite-icon-X2.png b/webroot/rsrc/image/sprite-icon-X2.png new file mode 100644 index 0000000000..5947f50335 Binary files /dev/null and b/webroot/rsrc/image/sprite-icon-X2.png differ diff --git a/webroot/rsrc/image/sprite-icon.png b/webroot/rsrc/image/sprite-icon.png new file mode 100644 index 0000000000..21296bbeac Binary files /dev/null and b/webroot/rsrc/image/sprite-icon.png differ