diff --git a/resources/celerity/map.php b/resources/celerity/map.php --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -7,7 +7,7 @@ */ return array( 'names' => array( - 'core.pkg.css' => 'f1325aa6', + 'core.pkg.css' => '974635bb', 'core.pkg.js' => 'f67c8265', 'darkconsole.pkg.js' => 'df001cab', 'differential.pkg.css' => '36884139', @@ -104,7 +104,7 @@ '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' => 'da8f5d5b', + 'rsrc/css/core/remarkup.css' => '45313445', 'rsrc/css/core/syntax.css' => '863f3cd8', 'rsrc/css/core/z-index.css' => '44e1d311', 'rsrc/css/diviner/diviner-shared.css' => '38813222', @@ -732,7 +732,7 @@ 'phabricator-phtize' => 'd254d646', 'phabricator-prefab' => 'bbae734c', 'phabricator-profile-css' => 'b459416e', - 'phabricator-remarkup-css' => 'da8f5d5b', + 'phabricator-remarkup-css' => '45313445', 'phabricator-search-results-css' => 'f240504c', 'phabricator-shaped-request' => '7cbe244b', 'phabricator-side-menu-view-css' => 'a2ccd7bd', diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1755,6 +1755,7 @@ 'PhabricatorMySQLFileStorageEngine' => 'applications/files/engine/PhabricatorMySQLFileStorageEngine.php', 'PhabricatorNamedQuery' => 'applications/search/storage/PhabricatorNamedQuery.php', 'PhabricatorNamedQueryQuery' => 'applications/search/query/PhabricatorNamedQueryQuery.php', + 'PhabricatorNavigationRemarkupRule' => 'infrastructure/markup/rule/PhabricatorNavigationRemarkupRule.php', 'PhabricatorNotificationAdHocFeedStory' => 'applications/notification/feed/PhabricatorNotificationAdHocFeedStory.php', 'PhabricatorNotificationBuilder' => 'applications/notification/builder/PhabricatorNotificationBuilder.php', 'PhabricatorNotificationClearController' => 'applications/notification/controller/PhabricatorNotificationClearController.php', @@ -4601,6 +4602,7 @@ 'PhabricatorPolicyInterface', ), 'PhabricatorNamedQueryQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', + 'PhabricatorNavigationRemarkupRule' => 'PhutilRemarkupRule', 'PhabricatorNotificationAdHocFeedStory' => 'PhabricatorFeedStory', 'PhabricatorNotificationClearController' => 'PhabricatorNotificationController', 'PhabricatorNotificationConfigOptions' => 'PhabricatorApplicationConfigOptions', diff --git a/src/docs/user/userguide/remarkup.diviner b/src/docs/user/userguide/remarkup.diviner --- a/src/docs/user/userguide/remarkup.diviner +++ b/src/docs/user/userguide/remarkup.diviner @@ -466,6 +466,7 @@ [[ http://fortawesome.github.io/Font-Awesome/ | FontAwesome ]], so you can also browse the collection there.) + = Phriction Documents = You can link to Phriction documents with a name or path: @@ -558,6 +559,36 @@ - you can use other Remarkup rules (like **bold**, //italics//, etc.) inside table cells. +Navigation Sequences +==================== + +You can use `{nav ...}` to render a stylized navigation sequence when helping +someone to locate something. This can be useful when writing documentation. +For example, you could give someone directions to purchase lemons: + +{nav icon=home, name=Home > +Grocery Store > +Produce Section > +icon=lemon-o, name=Lemons} + +To render this example, use this markup: + +``` +{nav icon=home, name=Home > +Grocery Store > +Produce Section > +icon=lemon-o, name=Lemons} +``` + +In general: + + - Separate sections with `>`. + - Each section can just have a name to add an element to the navigation + sequence, or a list of key-value pairs. + - Supported keys are `icon`, `name`, `type` and `href`. + - The `type` option can be set to `instructions` to indicate that an element + is asking the user to make a choice or follow specific instructions. + = Fullscreen Mode = Remarkup editors provide a fullscreen composition mode. This can make it easier diff --git a/src/infrastructure/markup/PhabricatorMarkupEngine.php b/src/infrastructure/markup/PhabricatorMarkupEngine.php --- a/src/infrastructure/markup/PhabricatorMarkupEngine.php +++ b/src/infrastructure/markup/PhabricatorMarkupEngine.php @@ -445,6 +445,7 @@ $rules[] = new PhutilRemarkupDocumentLinkRule(); + $rules[] = new PhabricatorNavigationRemarkupRule(); if ($options['youtube']) { $rules[] = new PhabricatorYoutubeRemarkupRule(); diff --git a/src/infrastructure/markup/rule/PhabricatorNavigationRemarkupRule.php b/src/infrastructure/markup/rule/PhabricatorNavigationRemarkupRule.php new file mode 100644 --- /dev/null +++ b/src/infrastructure/markup/rule/PhabricatorNavigationRemarkupRule.php @@ -0,0 +1,103 @@ +isFlatText($matches[0])) { + return $matches[0]; + } + + $elements = ltrim($matches[1], ", \n"); + $elements = explode('>', $elements); + + $defaults = array( + 'name' => null, + 'type' => 'link', + 'href' => null, + 'icon' => null, + ); + + $sequence = array(); + $parser = new PhutilSimpleOptions(); + foreach ($elements as $element) { + if (strpos($element, '=') === false) { + $sequence[] = array( + 'name' => trim($element), + ) + $defaults; + } else { + $sequence[] = $parser->parse($element) + $defaults; + } + } + + if ($this->getEngine()->isTextMode()) { + return implode(' > ', ipull($sequence, 'name')); + } + + static $icon_names; + if (!$icon_names) { + $icon_names = array_fuse(PHUIIconView::getFontIcons()); + } + + $out = array(); + foreach ($sequence as $item) { + $item_name = $item['name']; + $item_color = PHUITagView::COLOR_GREY; + if ($item['type'] == 'instructions') { + $item_name = phutil_tag('em', array(), $item_name); + $item_color = PHUITagView::COLOR_INDIGO; + } + + $tag = id(new PHUITagView()) + ->setType(PHUITagView::TYPE_SHADE) + ->setShade($item_color) + ->setName($item_name); + + if ($item['icon']) { + $icon_name = 'fa-'.$item['icon']; + if (isset($icon_names[$icon_name])) { + $tag->setIcon($icon_name); + } + } + + if ($item['href'] !== null) { + if (PhabricatorEnv::isValidWebResource($item['href'])) { + $tag->setHref($item['href']); + $tag->setExternal(true); + } + } + + $out[] = $tag; + } + + $joiner = phutil_tag( + 'span', + array( + 'class' => 'remarkup-nav-sequence-arrow', + ), + " \xE2\x86\x92 "); + + $out = phutil_implode_html($joiner, $out); + + $out = phutil_tag( + 'span', + array( + 'class' => 'remarkup-nav-sequence', + ), + $out); + + return $this->getEngine()->storeText($out); + } + + +} diff --git a/webroot/rsrc/css/core/remarkup.css b/webroot/rsrc/css/core/remarkup.css --- a/webroot/rsrc/css/core/remarkup.css +++ b/webroot/rsrc/css/core/remarkup.css @@ -466,3 +466,7 @@ margin: auto; max-width: 95%; } + +.remarkup-nav-sequence-arrow { + color: {$lightgreytext}; +}