diff --git a/scripts/celerity/generate_sprites.php b/scripts/celerity/generate_sprites.php index f3e8cf2e0d..84b3337be0 100755 --- a/scripts/celerity/generate_sprites.php +++ b/scripts/celerity/generate_sprites.php @@ -227,6 +227,31 @@ foreach ($action_map as $icon => $source) { ->setTargetCSS('.action-'.$icon)); } + +$remarkup_template = id(new PhutilSprite()) + ->setSourcePosition(0, 0) + ->setSourceSize(14, 14); + +$remarkup_icons = array( + 'b', + 'code', + 'i', + 'image', + 'ol', + 'tag', + 'tt', + 'ul', + 'help', +); + +foreach ($remarkup_icons as $icon) { + $sheet->addSprite( + id(clone $remarkup_template) + ->setSourceFile($srcroot.'remarkup/text_'.$icon.'.png') + ->setTargetCSS('.remarkup-assist-'.$icon)); +} + + $sheet->generateImage($webroot.'/image/autosprite.png'); $sheet->generateCSS($webroot.'/css/autosprite.css'); diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php index 7ab87b274f..de79d2cfeb 100644 --- a/src/__celerity_resource_map__.php +++ b/src/__celerity_resource_map__.php @@ -51,8 +51,8 @@ celerity_register_resource_map(array( ), '/rsrc/image/autosprite.png' => array( - 'hash' => 'c7f9d2dd752a24c518c0eb426a4853a5', - 'uri' => '/res/c7f9d2dd/rsrc/image/autosprite.png', + 'hash' => '005c7630a31cb2ef6b1782d4eca08cd7', + 'uri' => '/res/005c7630/rsrc/image/autosprite.png', 'disk' => '/rsrc/image/autosprite.png', 'type' => 'png', ), @@ -657,7 +657,7 @@ celerity_register_resource_map(array( ), 'autosprite-css' => array( - 'uri' => '/res/947e1dcf/rsrc/css/autosprite.css', + 'uri' => '/res/6c0c2948/rsrc/css/autosprite.css', 'type' => 'css', 'requires' => array( @@ -1559,7 +1559,7 @@ celerity_register_resource_map(array( ), 'javelin-behavior-phabricator-remarkup-assist' => array( - 'uri' => '/res/5f7ccd02/rsrc/js/application/core/behavior-phabricator-remarkup-assist.js', + 'uri' => '/res/d3b53e76/rsrc/js/application/core/behavior-phabricator-remarkup-assist.js', 'type' => 'js', 'requires' => array( @@ -2636,7 +2636,7 @@ celerity_register_resource_map(array( ), 'phabricator-remarkup-css' => array( - 'uri' => '/res/47c16585/rsrc/css/core/remarkup.css', + 'uri' => '/res/66b4cd42/rsrc/css/core/remarkup.css', 'type' => 'css', 'requires' => array( @@ -3003,7 +3003,7 @@ celerity_register_resource_map(array( ), array( 'packages' => array( - '782b1e3f' => + '1da0b408' => array( 'name' => 'core.pkg.css', 'symbols' => @@ -3032,7 +3032,7 @@ celerity_register_resource_map(array( 21 => 'phabricator-flag-css', 22 => 'aphront-error-view-css', ), - 'uri' => '/res/pkg/782b1e3f/core.pkg.css', + 'uri' => '/res/pkg/1da0b408/core.pkg.css', 'type' => 'css', ), '3a455e4f' => @@ -3199,20 +3199,20 @@ celerity_register_resource_map(array( 'reverse' => array( 'aphront-attached-file-view-css' => '7839ae2d', - 'aphront-crumbs-view-css' => '782b1e3f', - 'aphront-dialog-view-css' => '782b1e3f', - 'aphront-error-view-css' => '782b1e3f', - 'aphront-form-view-css' => '782b1e3f', + 'aphront-crumbs-view-css' => '1da0b408', + 'aphront-dialog-view-css' => '1da0b408', + 'aphront-error-view-css' => '1da0b408', + 'aphront-form-view-css' => '1da0b408', 'aphront-headsup-action-list-view-css' => '2ba14b3d', - 'aphront-headsup-view-css' => '782b1e3f', - 'aphront-list-filter-view-css' => '782b1e3f', - 'aphront-pager-view-css' => '782b1e3f', - 'aphront-panel-view-css' => '782b1e3f', - 'aphront-side-nav-view-css' => '782b1e3f', - 'aphront-table-view-css' => '782b1e3f', - 'aphront-tokenizer-control-css' => '782b1e3f', - 'aphront-tooltip-css' => '782b1e3f', - 'aphront-typeahead-control-css' => '782b1e3f', + 'aphront-headsup-view-css' => '1da0b408', + 'aphront-list-filter-view-css' => '1da0b408', + 'aphront-pager-view-css' => '1da0b408', + 'aphront-panel-view-css' => '1da0b408', + 'aphront-side-nav-view-css' => '1da0b408', + 'aphront-table-view-css' => '1da0b408', + 'aphront-tokenizer-control-css' => '1da0b408', + 'aphront-tooltip-css' => '1da0b408', + 'aphront-typeahead-control-css' => '1da0b408', 'differential-changeset-view-css' => '2ba14b3d', 'differential-core-view-css' => '2ba14b3d', 'differential-inline-comment-editor' => 'd05e3c0f', @@ -3278,15 +3278,15 @@ celerity_register_resource_map(array( 'javelin-workflow' => '3a455e4f', 'maniphest-task-summary-css' => '7839ae2d', 'maniphest-transaction-detail-css' => '7839ae2d', - 'phabricator-app-buttons-css' => '782b1e3f', + 'phabricator-app-buttons-css' => '1da0b408', 'phabricator-content-source-view-css' => '2ba14b3d', - 'phabricator-core-buttons-css' => '782b1e3f', - 'phabricator-core-css' => '782b1e3f', - 'phabricator-directory-css' => '782b1e3f', + 'phabricator-core-buttons-css' => '1da0b408', + 'phabricator-core-css' => '1da0b408', + 'phabricator-directory-css' => '1da0b408', 'phabricator-drag-and-drop-file-upload' => 'd05e3c0f', 'phabricator-dropdown-menu' => '3a455e4f', - 'phabricator-flag-css' => '782b1e3f', - 'phabricator-jump-nav' => '782b1e3f', + 'phabricator-flag-css' => '1da0b408', + 'phabricator-jump-nav' => '1da0b408', 'phabricator-keyboard-shortcut' => '3a455e4f', 'phabricator-keyboard-shortcut-manager' => '3a455e4f', 'phabricator-menu-item' => '3a455e4f', @@ -3294,11 +3294,11 @@ celerity_register_resource_map(array( 'phabricator-paste-file-upload' => '3a455e4f', 'phabricator-prefab' => '3a455e4f', 'phabricator-project-tag-css' => '7839ae2d', - 'phabricator-remarkup-css' => '782b1e3f', + 'phabricator-remarkup-css' => '1da0b408', 'phabricator-shaped-request' => 'd05e3c0f', - 'phabricator-standard-page-view' => '782b1e3f', + 'phabricator-standard-page-view' => '1da0b408', 'phabricator-tooltip' => '3a455e4f', - 'phabricator-transaction-view-css' => '782b1e3f', - 'syntax-highlighting-css' => '782b1e3f', + 'phabricator-transaction-view-css' => '1da0b408', + 'syntax-highlighting-css' => '1da0b408', ), )); diff --git a/src/view/form/control/PhabricatorRemarkupControl.php b/src/view/form/control/PhabricatorRemarkupControl.php index 7466547fba..3066b1c2bd 100644 --- a/src/view/form/control/PhabricatorRemarkupControl.php +++ b/src/view/form/control/PhabricatorRemarkupControl.php @@ -21,50 +21,33 @@ final class PhabricatorRemarkupControl extends AphrontFormTextAreaControl { protected function renderInput() { Javelin::initBehavior('phabricator-remarkup-assist', array()); + Javelin::initBehavior('phabricator-tooltips', array()); $actions = array( 'b' => array( - 'text' => 'B', + 'tip' => pht('Bold'), ), 'i' => array( - 'text' => 'I', + 'tip' => pht('Italics'), ), 'tt' => array( - 'text' => 'T', - ), - 's' => array( - 'text' => 'S', + 'tip' => pht('Monospaced'), ), array( 'spacer' => true, ), 'ul' => array( - 'text' => "\xE2\x80\xA2", + 'tip' => pht('Bulleted List'), ), 'ol' => array( - 'text' => '1.', + 'tip' => pht('Numbered List'), ), 'code' => array( - 'text' => '{}', - ), - array( - 'spacer' => true, - ), - 'mention' => array( - 'text' => '@', - ), - array( - 'spacer' => true, - ), - 'h1' => array( - 'text' => 'H', - ), - array( - 'spacer' => true, + 'tip' => pht('Code Block'), ), 'help' => array( + 'tip' => pht('Help'), 'align' => 'right', - 'text' => '?', 'href' => PhabricatorEnv::getDoclink( 'article/Remarkup_Reference.html'), ), @@ -73,13 +56,16 @@ final class PhabricatorRemarkupControl extends AphrontFormTextAreaControl { $buttons = array(); foreach ($actions as $action => $spec) { if (idx($spec, 'spacer')) { - $buttons[] = ' '; + $buttons[] = phutil_render_tag( + 'span', + array( + 'class' => 'remarkup-assist-separator', + ), + ''); continue; } $classes = array(); - $classes[] = 'button'; - $classes[] = 'grey'; $classes[] = 'remarkup-assist-button'; if (idx($spec, 'align') == 'right') { $classes[] = 'remarkup-assist-right'; @@ -91,17 +77,22 @@ final class PhabricatorRemarkupControl extends AphrontFormTextAreaControl { $mustcapture = true; $target = null; } else { - $meta = null; + $meta = array(); $mustcapture = null; $target = '_blank'; } + $tip = idx($spec, 'tip'); + if ($tip) { + $meta['tip'] = $tip; + } + $buttons[] = javelin_render_tag( 'a', array( 'class' => implode(' ', $classes), 'href' => $href, - 'sigil' => 'remarkup-assist', + 'sigil' => 'remarkup-assist has-tooltip', 'meta' => $meta, 'mustcapture' => $mustcapture, 'target' => $target, @@ -110,12 +101,19 @@ final class PhabricatorRemarkupControl extends AphrontFormTextAreaControl { phutil_render_tag( 'div', array( - 'class' => 'remarkup-assist remarkup-assist-'.$action, + 'class' => 'remarkup-assist autosprite remarkup-assist-'.$action, ), - idx($spec, 'text', ''))); + '')); } - $buttons = implode('', $buttons); + $buttons = phutil_render_tag( + 'div', + array( + 'class' => 'remarkup-assist-bar', + ), + implode('', $buttons)); + + $this->setCustomClass('remarkup-assist-textarea'); return javelin_render_tag( 'div', diff --git a/webroot/rsrc/css/autosprite.css b/webroot/rsrc/css/autosprite.css index 66aaffc597..233b280681 100644 --- a/webroot/rsrc/css/autosprite.css +++ b/webroot/rsrc/css/autosprite.css @@ -747,3 +747,39 @@ .action-subscribe-delete { background-position: 0px -7308px; } + +.remarkup-assist-b { + background-position: 0px -7325px; +} + +.remarkup-assist-code { + background-position: 0px -7340px; +} + +.remarkup-assist-i { + background-position: 0px -7355px; +} + +.remarkup-assist-image { + background-position: 0px -7370px; +} + +.remarkup-assist-ol { + background-position: 0px -7385px; +} + +.remarkup-assist-tag { + background-position: 0px -7400px; +} + +.remarkup-assist-tt { + background-position: 0px -7415px; +} + +.remarkup-assist-ul { + background-position: 0px -7430px; +} + +.remarkup-assist-help { + background-position: 0px -7445px; +} diff --git a/webroot/rsrc/css/core/remarkup.css b/webroot/rsrc/css/core/remarkup.css index 527b3b6185..cc4705c726 100644 --- a/webroot/rsrc/css/core/remarkup.css +++ b/webroot/rsrc/css/core/remarkup.css @@ -247,63 +247,72 @@ img.phabricator-remarkup-embed-image { padding: 3px 6px; } + +.remarkup-assist-textarea { + border-width: 1px; + border-color: #e5e5e5 #999999 #999999; + + /* Prevent Safari and Chrome users from dragging the textarea any wider, + because the top bar won't resize along with it. */ + resize: vertical; +} + .remarkup-assist-bar { - padding: 2px 0; -} + height: 27px; + padding: 0 2px; -a.remarkup-assist-button { - padding-left: 4px; - padding-right: 4px; - padding-bottom: 4px; - margin-bottom: 3px; + border-width: 1px 1px 0; + border-style: solid; + border-color: #737373 #999999; - position: relative; + background: #f5f5f5; overflow: hidden; - height: 16px; - width: 16px; } -a.remarkup-assist-button + a.remarkup-assist-button { - border-left-width: 0px; +.remarkup-assist-button { + display: block; + padding: 3px; + margin: 2px 1px; + float: left; + + border: 1px solid transparent; + border-radius: 2px; +} + +.remarkup-assist-button:hover { + background: #f7f7f7; + border-color: #c6c6c6; + box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.10); +} + +.remarkup-assist-button:active { + outline: none; + background: #f3f3f3; + box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.10); +} + +.remarkup-assist-button:focus { + outline: none; +} + +.remarkup-assist-separator { + display: block; + float: left; + + margin: 7px 4px; + height: 14px; + + width: 0px; + border-right: 1px solid #cccccc; } .remarkup-assist { - float: left; - height: 16px; - width: 16px; - font-weight: normal; + display: block; + width: 14px; + height: 14px; + overflow: hidden; } .remarkup-assist-right { float: right; } - -.remarkup-assist-b { - font-family: "Georgia", serif; - font-weight: bold; -} - -.remarkup-assist-i { - font-family: "Georgia", serif; - font-style: italic; -} - -.remarkup-assist-code, -.remarkup-assist-tt { - text-align: center; - font-family: monospace; -} - -.remarkup-assist-s { - font-family: "Georgia", serif; - text-decoration: line-through; -} - -.remarkup-assist-ol { - font-family: "Georgia", serif; -} - -.remarkup-assist-h1 { - font-family: "Georgia", serif; - font-weight: bold; -} diff --git a/webroot/rsrc/image/autosprite.png b/webroot/rsrc/image/autosprite.png index 4b8c03ad51..c8a56e2367 100644 Binary files a/webroot/rsrc/image/autosprite.png and b/webroot/rsrc/image/autosprite.png differ diff --git a/webroot/rsrc/js/application/core/behavior-phabricator-remarkup-assist.js b/webroot/rsrc/js/application/core/behavior-phabricator-remarkup-assist.js index e5b56167d8..01c46d5b70 100644 --- a/webroot/rsrc/js/application/core/behavior-phabricator-remarkup-assist.js +++ b/webroot/rsrc/js/application/core/behavior-phabricator-remarkup-assist.js @@ -39,9 +39,6 @@ JX.behavior('phabricator-remarkup-assist', function(config) { case 'tt': update(area, '`', sel || 'monospaced text', '`'); break; - case 's': - update(area, '~~', sel || 'strikethrough text', '~~'); - break; case 'ul': case 'ol': var ch = (action == 'ol') ? ' # ' : ' - '; @@ -59,13 +56,6 @@ JX.behavior('phabricator-remarkup-assist', function(config) { sel = " " + sel.join("\n "); update(area, ((r.start == 0) ? "" : "\n\n"), sel, "\n\n"); break; - case 'mention': - update(area, '@', sel || 'username', ''); - break; - case 'h1': - sel = sel || 'Header'; - update(area, ((r.start == 0) ? "" : "\n\n") + "= ", sel, " =\n\n"); - break; } }