Page MenuHomestyx hydra

No OneTemporary

diff --git a/scripts/celerity/generate_sprites.php b/scripts/celerity/generate_sprites.php
index a6f2b109b5..b44e61f1e3 100755
--- a/scripts/celerity/generate_sprites.php
+++ b/scripts/celerity/generate_sprites.php
@@ -1,261 +1,264 @@
#!/usr/bin/env php
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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' => 'source',
'param' => 'directory',
'help' => 'Directory with sprite sources.',
)
));
$srcroot = $args->getArg('source');
if (!$srcroot) {
throw new Exception(
"You must specify a source directory with '--source'.");
}
$webroot = dirname(phutil_get_library_root('phabricator')).'/webroot/rsrc';
$webroot = Filesystem::readablePath($webroot);
function glx($x) {
return (60 + (48 * $x));
}
function gly($y) {
return (110 + (48 * $y));
}
$sheet = new PhutilSpriteSheet();
$at = '@';
$sheet->setCSSHeader(<<<EOCSS
/**
* @provides autosprite-css
* {$at}generated
*/
.autosprite {
background-image: url(/rsrc/image/autosprite.png);
background-repeat: no-repeat;
}
EOCSS
);
$menu_normal_template = id(new PhutilSprite())
->setSourceFile($srcroot.'/menu_normal_1x.png')
->setSourceSize(26, 26);
$menu_hover_template = id(new PhutilSprite())
->setSourceFile($srcroot.'/menu_hover_1x.png')
->setSourceSize(26, 26);
$menu_selected_template = id(new PhutilSprite())
->setSourceFile($srcroot.'/menu_selected_1x.png')
->setSourceSize(26, 26);
$menu_map = array(
'' => $menu_normal_template,
'-selected' => $menu_selected_template,
':hover' => $menu_hover_template,
);
$icon_map = array(
'help' => array(4, 19),
'settings' => array(0, 28),
'logout' => array(3, 6),
'notifications' => array(5, 20),
'task' => array(1, 15),
);
foreach ($icon_map as $icon => $coords) {
list($x, $y) = $coords;
foreach ($menu_map as $suffix => $template) {
$sheet->addSprite(
id(clone $template)
->setSourcePosition(glx($x), gly($y))
->setTargetCSS('.main-menu-item-icon-'.$icon.$suffix));
}
}
$app_template_large = id(new PhutilSprite())
->setSourceFile($srcroot.'/application_large_1x.png')
->setSourceSize(60, 60);
$app_template_large_hover = id(new PhutilSprite())
->setSourceFile($srcroot.'/application_large_hover_1x.png')
->setSourceSize(60, 60);
$app_template_small = id(new PhutilSprite())
->setSourceFile($srcroot.'/menu_normal_1x.png')
->setSourceSize(30, 30);
$app_template_small_hover = id(new PhutilSprite())
->setSourceFile($srcroot.'/menu_hover_1x.png')
->setSourceSize(30, 30);
$app_template_small_selected = id(new PhutilSprite())
->setSourceFile($srcroot.'/menu_selected_1x.png')
->setSourceSize(30, 30);
$app_source_map = array(
'-large' => array($app_template_large, 2),
// For the application launch view, we only show hover state on the desktop
// because it looks glitchy on touch devices. We show the hover state when
// the surrounding <a> is hovered, not the icon itself.
'-large /* hover */' => array(
$app_template_large_hover,
2,
'.device-desktop .phabricator-application-launch-container:hover '),
'' => array($app_template_small, 1),
// Show hover state only for the desktop.
':hover' => array(
$app_template_small_hover,
1,
'.device-desktop ',
),
'-selected' => array($app_template_small_selected, 1),
);
$app_map = array(
'differential' => array(9, 1),
'fact' => array(2, 4),
'mail' => array(0, 1),
'diffusion' => array(7, 13),
'slowvote' => array(1, 4),
'phriction' => array(1, 7),
'maniphest' => array(3, 24),
'flags' => array(6, 26),
'settings' => array(9, 11),
'applications' => array(0, 34),
'default' => array(9, 9),
'people' => array(3, 0),
'ponder' => array(4, 35),
'calendar' => array(5, 4),
'files' => array(6, 3),
'projects' => array(7, 35),
'daemons' => array(7, 6),
'herald' => array(1, 5),
'countdown' => array(7, 5),
'conduit' => array(7, 30),
'feed' => array(3, 11),
'paste' => array(9, 2),
'audit' => array(8, 19),
'uiexample' => array(7, 28),
'phpast' => array(6, 31),
'owners' => array(5, 32),
'phid' => array(9, 25),
'diviner' => array(1, 35),
'repositories' => array(8, 13),
'phame' => array(8, 4),
'macro' => array(0, 31),
);
$xadj = -1;
foreach ($app_map as $icon => $coords) {
list($x, $y) = $coords;
foreach ($app_source_map as $suffix => $spec) {
list($template, $scale) = $spec;
if (isset($spec[2])) {
$prefix = $spec[2];
} else {
$prefix = '';
}
$sheet->addSprite(
id(clone $template)
->setSourcePosition(($xadj + glx($x)) * $scale, gly($y) * $scale)
->setTargetCSS($prefix.'.app-'.$icon.$suffix));
}
}
$action_template = id(new PhutilSprite())
->setSourcePosition(0, 0)
->setSourceSize(16, 16);
$action_map = array(
'file' => 'icon/page_white_text.png',
'fork' => 'icon/arrow_branch.png',
'edit' => 'icon/page_white_edit.png',
'flag-0' => 'icon/flag-0.png',
'flag-1' => 'icon/flag-1.png',
'flag-2' => 'icon/flag-2.png',
'flag-3' => 'icon/flag-3.png',
'flag-4' => 'icon/flag-4.png',
'flag-5' => 'icon/flag-5.png',
'flag-6' => 'icon/flag-6.png',
'flag-7' => 'icon/flag-7.png',
'flag-ghost' => 'icon/flag-ghost.png',
'subscribe-auto' => 'icon/unsubscribe.png',
'subscribe-add' => 'icon/subscribe.png',
'subscribe-delete' => 'icon/unsubscribe.png',
'new' => 'icon/page_white_put.png',
'world' => 'icon/world.png',
- 'delete' => 'icon/delete.png',
+ 'delete' => 'icon/page_delete.png',
+ 'move' => 'icon/page_go.png',
+ 'preview' => 'icon/page_world.png',
+ 'unpublish' => 'icon/page_error.png',
);
foreach ($action_map as $icon => $source) {
$sheet->addSprite(
id(clone $action_template)
->setSourceFile($srcroot.$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');
echo "Done.\n";
diff --git a/src/applications/phame/application/PhabricatorApplicationPhame.php b/src/applications/phame/application/PhabricatorApplicationPhame.php
index 5867f9d194..84ca525a9c 100644
--- a/src/applications/phame/application/PhabricatorApplicationPhame.php
+++ b/src/applications/phame/application/PhabricatorApplicationPhame.php
@@ -1,77 +1,78 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
final class PhabricatorApplicationPhame extends PhabricatorApplication {
public function getBaseURI() {
return '/phame/';
}
public function getAutospriteName() {
return 'phame';
}
public function getShortDescription() {
return 'Blog';
}
public function getTitleGlyph() {
return "\xe2\x9c\xa9";
}
public function getHelpURI() {
return PhabricatorEnv::getDoclink('article/Phame_User_Guide.html');
}
public function getApplicationGroup() {
return self::GROUP_COMMUNICATION;
}
public function getRoutes() {
return array(
'/phame/' => array(
'' => 'PhamePostListController',
'live/(?P<id>[^/]+)/(?P<more>.*)' => 'PhameBlogLiveController',
'post/' => array(
'(?:(?P<filter>draft|all)/)?' => 'PhamePostListController',
'blogger/(?P<bloggername>[\w\.-_]+)/' => 'PhamePostListController',
'delete/(?P<id>[^/]+)/' => 'PhamePostDeleteController',
'edit/(?:(?P<id>[^/]+)/)?' => 'PhamePostEditController',
'view/(?P<id>\d+)/' => 'PhamePostViewController',
'publish/(?P<id>\d+)/' => 'PhamePostPublishController',
'unpublish/(?P<id>\d+)/' => 'PhamePostUnpublishController',
'notlive/(?P<id>\d+)/' => 'PhamePostNotLiveController',
'preview/' => 'PhamePostPreviewController',
'framed/(?P<id>\d+)/' => 'PhamePostFramedController',
'new/' => 'PhamePostNewController',
+ 'move/(?P<id>\d+)/' => 'PhamePostNewController'
),
'blog/' => array(
'(?:(?P<filter>user|all)/)?' => 'PhameBlogListController',
'delete/(?P<id>[^/]+)/' => 'PhameBlogDeleteController',
'edit/(?P<id>[^/]+)/' => 'PhameBlogEditController',
'view/(?P<id>[^/]+)/' => 'PhameBlogViewController',
'new/' => 'PhameBlogEditController',
),
'posts/' => array(
'(?P<bloggername>\w+)/(?P<phametitle>.+/)'
=> 'PhamePostViewController',
),
),
);
}
}
diff --git a/src/applications/phame/controller/blog/PhameBlogEditController.php b/src/applications/phame/controller/blog/PhameBlogEditController.php
index 35cddc9b52..4b953d2bd0 100644
--- a/src/applications/phame/controller/blog/PhameBlogEditController.php
+++ b/src/applications/phame/controller/blog/PhameBlogEditController.php
@@ -1,208 +1,208 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @group phame
*/
final class PhameBlogEditController
extends PhameController {
private $id;
public function willProcessRequest(array $data) {
$this->id = idx($data, 'id');
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
if ($this->id) {
$blog = id(new PhameBlogQuery())
->setViewer($user)
->withIDs(array($this->id))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_EDIT
))
->executeOne();
if (!$blog) {
return new Aphront404Response();
}
$submit_button = pht('Save Changes');
$page_title = pht('Edit Blog');
$cancel_uri = $this->getApplicationURI('blog/view/'.$blog->getID().'/');
} else {
$blog = id(new PhameBlog())
->setCreatorPHID($user->getPHID());
$blog->setViewPolicy(PhabricatorPolicies::POLICY_USER);
$blog->setEditPolicy(PhabricatorPolicies::POLICY_USER);
$blog->setJoinPolicy(PhabricatorPolicies::POLICY_USER);
$submit_button = pht('Create Blog');
$page_title = pht('Create Blog');
$cancel_uri = $this->getApplicationURI();
}
$e_name = true;
$e_custom_domain = null;
$errors = array();
if ($request->isFormPost()) {
$name = $request->getStr('name');
$description = $request->getStr('description');
$custom_domain = $request->getStr('custom_domain');
$skin = $request->getStr('skin');
if (empty($name)) {
$errors[] = 'You must give the blog a name.';
$e_name = 'Required';
} else {
$e_name = null;
}
$blog->setName($name);
$blog->setDescription($description);
- $blog->setDomain($custom_domain);
+ $blog->setDomain(nonempty($custom_domain, null));
$blog->setSkin($skin);
if (!empty($custom_domain)) {
$error = $blog->validateCustomDomain($custom_domain);
if ($error) {
$errors[] = $error;
$e_custom_domain = 'Invalid';
}
}
$blog->setViewPolicy($request->getStr('can_view'));
$blog->setEditPolicy($request->getStr('can_edit'));
$blog->setJoinPolicy($request->getStr('can_join'));
// Don't let users remove their ability to edit blogs.
PhabricatorPolicyFilter::mustRetainCapability(
$user,
$blog,
PhabricatorPolicyCapability::CAN_EDIT);
if (!$errors) {
try {
$blog->save();
return id(new AphrontRedirectResponse())
->setURI($this->getApplicationURI('blog/view/'.$blog->getID().'/'));
} catch (AphrontQueryDuplicateKeyException $ex) {
$errors[] = 'Domain must be unique.';
$e_custom_domain = 'Not Unique';
}
}
}
$policies = id(new PhabricatorPolicyQuery())
->setViewer($user)
->setObject($blog)
->execute();
$form = id(new AphrontFormView())
->setUser($user)
->setFlexible(true)
->appendChild(
id(new AphrontFormTextControl())
->setLabel('Name')
->setName('name')
->setValue($blog->getName())
->setID('blog-name')
->setError($e_name)
)
->appendChild(
id(new PhabricatorRemarkupControl())
->setLabel('Description')
->setName('description')
->setValue($blog->getDescription())
->setID('blog-description')
)
->appendChild(
id(new AphrontFormPolicyControl())
->setUser($user)
->setCapability(PhabricatorPolicyCapability::CAN_VIEW)
->setPolicyObject($blog)
->setPolicies($policies)
->setName('can_view'))
->appendChild(
id(new AphrontFormPolicyControl())
->setUser($user)
->setCapability(PhabricatorPolicyCapability::CAN_EDIT)
->setPolicyObject($blog)
->setPolicies($policies)
->setName('can_edit'))
->appendChild(
id(new AphrontFormPolicyControl())
->setUser($user)
->setCapability(PhabricatorPolicyCapability::CAN_JOIN)
->setPolicyObject($blog)
->setPolicies($policies)
->setName('can_join'))
->appendChild(
id(new AphrontFormTextControl())
->setLabel('Custom Domain')
->setName('custom_domain')
->setValue($blog->getDomain())
->setCaption('Must include at least one dot (.), e.g. '.
'blog.example.com')
->setError($e_custom_domain)
)
->appendChild(
id(new AphrontFormSelectControl())
->setLabel('Skin')
->setName('skin')
->setValue($blog->getSkin())
->setOptions(PhameBlog::getSkinOptionsForSelect())
)
->appendChild(
id(new AphrontFormSubmitControl())
->addCancelButton($cancel_uri)
->setValue($submit_button)
);
if ($errors) {
$error_view = id(new AphrontErrorView())
->setTitle('Form Errors')
->setErrors($errors);
} else {
$error_view = null;
}
$header = id(new PhabricatorHeaderView())
->setHeader($page_title);
$nav = $this->renderSideNavFilterView();
$nav->selectFilter($this->id ? null : 'blog/new');
$nav->appendChild(
array(
$header,
$error_view,
$form,
));
return $this->buildApplicationPage(
$nav,
array(
'title' => $page_title,
));
}
}
diff --git a/src/applications/phame/controller/blog/PhameBlogViewController.php b/src/applications/phame/controller/blog/PhameBlogViewController.php
index 7533d0b86b..8475cee454 100644
--- a/src/applications/phame/controller/blog/PhameBlogViewController.php
+++ b/src/applications/phame/controller/blog/PhameBlogViewController.php
@@ -1,172 +1,172 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @group phame
*/
final class PhameBlogViewController extends PhameController {
private $id;
public function willProcessRequest(array $data) {
$this->id = $data['id'];
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$blog = id(new PhameBlogQuery())
->setViewer($user)
->withIDs(array($this->id))
->executeOne();
if (!$blog) {
return new Aphront404Response();
}
$pager = id(new AphrontCursorPagerView())
->readFromRequest($request);
$posts = id(new PhamePostQuery())
->setViewer($user)
->withBlogPHIDs(array($blog->getPHID()))
->executeWithCursorPager($pager);
$nav = $this->renderSideNavFilterView(null);
$header = id(new PhabricatorHeaderView())
->setHeader($blog->getName());
$handle_phids = array_merge(
mpull($posts, 'getBloggerPHID'),
mpull($posts, 'getBlogPHID'));
$this->loadHandles($handle_phids);
$actions = $this->renderActions($blog, $user);
$properties = $this->renderProperties($blog, $user);
$post_list = $this->renderPostList(
$posts,
$user,
pht('This blog has no visible posts.'));
$nav->appendChild(
array(
$header,
$actions,
$properties,
$post_list,
));
return $this->buildApplicationPage(
$nav,
array(
'device' => true,
'title' => $blog->getName(),
));
}
private function renderProperties(PhameBlog $blog, PhabricatorUser $user) {
$properties = new PhabricatorPropertyListView();
$properties->addProperty(
pht('Skin'),
phutil_escape_html($blog->getSkin()));
$properties->addProperty(
pht('Domain'),
phutil_escape_html($blog->getDomain()));
$descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions(
$user,
$blog);
$properties->addProperty(
pht('Visible To'),
$descriptions[PhabricatorPolicyCapability::CAN_VIEW]);
$properties->addProperty(
pht('Editable By'),
$descriptions[PhabricatorPolicyCapability::CAN_EDIT]);
$properties->addProperty(
pht('Joinable By'),
$descriptions[PhabricatorPolicyCapability::CAN_JOIN]);
$engine = id(new PhabricatorMarkupEngine())
->setViewer($user)
->addObject($blog, PhameBlog::MARKUP_FIELD_DESCRIPTION)
->process();
$properties->addTextContent(
'<div class="phabricator-remarkup">'.
$engine->getOutput($blog, PhameBlog::MARKUP_FIELD_DESCRIPTION).
'</div>');
return $properties;
}
private function renderActions(PhameBlog $blog, PhabricatorUser $user) {
$actions = id(new PhabricatorActionListView())
->setObject($blog)
->setUser($user);
$can_edit = PhabricatorPolicyFilter::hasCapability(
$user,
$blog,
PhabricatorPolicyCapability::CAN_EDIT);
$can_join = PhabricatorPolicyFilter::hasCapability(
$user,
$blog,
PhabricatorPolicyCapability::CAN_JOIN);
$actions->addAction(
id(new PhabricatorActionView())
->setIcon('new')
- ->setHref($this->getApplicationURI('post/new/?blog='.$blog->getID()))
+ ->setHref($this->getApplicationURI('post/edit/?blog='.$blog->getID()))
->setName(pht('Write Post'))
->setDisabled(!$can_join)
->setWorkflow(!$can_join));
$actions->addAction(
id(new PhabricatorActionView())
->setIcon('world')
->setHref($this->getApplicationURI('live/'.$blog->getID().'/'))
->setName(pht('View Live')));
$actions->addAction(
id(new PhabricatorActionView())
->setIcon('edit')
->setHref($this->getApplicationURI('blog/edit/'.$blog->getID().'/'))
->setName('Edit Blog')
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit));
$actions->addAction(
id(new PhabricatorActionView())
->setIcon('delete')
->setHref($this->getApplicationURI('blog/delete/'.$blog->getID().'/'))
->setName('Delete Blog')
->setDisabled(!$can_edit)
->setWorkflow(true));
return $actions;
}
}
diff --git a/src/applications/phame/controller/post/PhamePostNewController.php b/src/applications/phame/controller/post/PhamePostNewController.php
index 6393c2d9b0..60b7056e67 100644
--- a/src/applications/phame/controller/post/PhamePostNewController.php
+++ b/src/applications/phame/controller/post/PhamePostNewController.php
@@ -1,77 +1,140 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @group phame
*/
final class PhamePostNewController extends PhameController {
+ private $id;
+
+ public function willProcessRequest(array $data) {
+ $this->id = idx($data, 'id');
+ }
+
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
+ $post = null;
+ $view_uri = null;
+ if ($this->id) {
+ $post = id(new PhamePostQuery())
+ ->setViewer($user)
+ ->withIDs(array($this->id))
+ ->requireCapabilities(
+ array(
+ PhabricatorPolicyCapability::CAN_EDIT,
+ ))
+ ->executeOne();
+ if (!$post) {
+ return new Aphront404Response();
+ }
+
+ $view_uri = '/post/view/'.$post->getID().'/';
+ $view_uri = $this->getApplicationURI($view_uri);
+
+ if ($request->isFormPost()) {
+ $blog = id(new PhameBlogQuery())
+ ->setViewer($user)
+ ->withIDs(array($request->getInt('blog')))
+ ->requireCapabilities(
+ array(
+ PhabricatorPolicyCapability::CAN_JOIN,
+ ))
+ ->executeOne();
+
+ if ($blog) {
+ $post->setBlogPHID($blog->getPHID());
+ $post->save();
+
+ return id(new AphrontRedirectResponse())->setURI($view_uri);
+ }
+ }
+
+ $title = pht('Move Post');
+ } else {
+ $title = pht('Create Post');
+ }
+
$blogs = id(new PhameBlogQuery())
->setViewer($user)
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_JOIN,
))
->execute();
$nav = $this->renderSideNavFilterView();
$nav->selectFilter('post/new');
$nav->appendChild(
- id(new PhabricatorHeaderView())->setHeader(
- pht('Create Post')));
+ id(new PhabricatorHeaderView())->setHeader($title));
if (!$blogs) {
$notification = id(new AphrontErrorView())
->setSeverity(AphrontErrorView::SEVERITY_NODATA)
->appendChild(
pht('You do not have permission to join any blogs. Create a blog '.
'first, then you can post to it.'));
$nav->appendChild($notification);
} else {
$options = mpull($blogs, 'getName', 'getID');
+ asort($options);
+
+ $selected_value = null;
+ if ($post && $post->getBlog()) {
+ $selected_value = $post->getBlog()->getID();
+ }
$form = id(new AphrontFormView())
->setUser($user)
- ->setMethod('GET')
->setFlexible(true)
- ->setAction($this->getApplicationURI('post/edit/'))
->appendChild(
id(new AphrontFormSelectControl())
->setLabel('Blog')
->setName('blog')
- ->setOptions($options))
- ->appendChild(
- id(new AphrontFormSubmitControl())
- ->setValue('Continue'));
+ ->setOptions($options)
+ ->setValue($selected_value));
+
+ if ($post) {
+ $form
+ ->appendChild(
+ id(new AphrontFormSubmitControl())
+ ->setValue(pht('Move Post'))
+ ->addCancelButton($view_uri));
+ } else {
+ $form
+ ->setAction($this->getApplicationURI('post/edit/'))
+ ->setMethod('GET')
+ ->appendChild(
+ id(new AphrontFormSubmitControl())
+ ->setValue(pht('Continue')));
+ }
$nav->appendChild($form);
}
return $this->buildApplicationPage(
$nav,
array(
- 'title' => 'Create Post',
+ 'title' => $title,
'device' => true,
));
}
}
diff --git a/src/applications/phame/controller/post/PhamePostNotLiveController.php b/src/applications/phame/controller/post/PhamePostNotLiveController.php
index 9676a11ad8..8d5cb3715b 100644
--- a/src/applications/phame/controller/post/PhamePostNotLiveController.php
+++ b/src/applications/phame/controller/post/PhamePostNotLiveController.php
@@ -1,79 +1,79 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @group phame
*/
final class PhamePostNotLiveController extends PhameController {
private $id;
public function willProcessRequest(array $data) {
$this->id = $data['id'];
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$post = id(new PhamePostQuery())
->setViewer($user)
->withIDs(array($this->id))
->executeOne();
if (!$post) {
return new Aphront404Response();
}
$reasons = array();
if (!$post->getBlog()) {
$reasons[] =
'<p>'.pht('You can not view the live version of this post because it '.
- 'is not associated with a blog. Edit the post and choose a blog to '.
- 'publish it to.').'</p>';
+ 'is not associated with a blog. Move the post to a blog in order to '.
+ 'view it live.').'</p>';
}
if ($post->isDraft()) {
$reasons[] =
'<p>'.pht('You can not view the live version of this post because it '.
'is still a draft. Use "Preview/Publish" to publish the post.').'</p>';
}
if ($reasons) {
$cancel_uri = $this->getApplicationURI('/post/view/'.$post->getID().'/');
$dialog = id(new AphrontDialogView())
->setUser($user)
->setTitle(pht('Post Not Live'))
->addCancelButton($cancel_uri);
foreach ($reasons as $reason) {
$dialog->appendChild($reason);
}
return id(new AphrontDialogResponse())->setDialog($dialog);
}
// No reason this can't go live, maybe an old link. Kick them live and see
// what happens.
$blog = $post->getBlog();
$live_uri = 'http://'.$blog->getDomain().'/'.$post->getPhameTitle();
return id(new AphrontRedirectResponse())->setURI($live_uri);
}
}
diff --git a/src/applications/phame/controller/post/PhamePostViewController.php b/src/applications/phame/controller/post/PhamePostViewController.php
index affbfbda81..626a1704c4 100644
--- a/src/applications/phame/controller/post/PhamePostViewController.php
+++ b/src/applications/phame/controller/post/PhamePostViewController.php
@@ -1,204 +1,209 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @group phame
*/
final class PhamePostViewController extends PhameController {
private $id;
public function willProcessRequest(array $data) {
$this->id = $data['id'];
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$post = id(new PhamePostQuery())
->setViewer($user)
->withIDs(array($this->id))
->executeOne();
if (!$post) {
return new Aphront404Response();
}
+ $nav = $this->renderSideNavFilterView();
+
+ $nav->appendChild(
+ id(new PhabricatorHeaderView())
+ ->setHeader($post->getTitle()));
+
if ($post->isDraft()) {
- $notice = array(
- 'title' => 'You are previewing a draft.',
- 'body' => 'Only you can see this draft until you publish it. '.
- 'If you chose a comment widget it will show up when '.
- 'you publish.'
- );
- } else if ($request->getExists('saved')) {
- $new_link = phutil_render_tag(
- 'a',
- array(
- 'href' => '/phame/post/new/',
- 'class' => 'button green',
- ),
- 'write another blog post'
- );
- $notice = array(
- 'title' => 'Saved post successfully.',
- 'body' => 'Seek even more phame and '.$new_link.'.'
- );
- } else {
- $notice = array();
+ $nav->appendChild(
+ id(new AphrontErrorView())
+ ->setSeverity(AphrontErrorView::SEVERITY_NOTICE)
+ ->setTitle(pht('Draft Post'))
+ ->appendChild(
+ pht('Only you can see this draft until you publish it. '.
+ 'Use "Preview / Publish" to publish this post.')));
+ }
+
+ if (!$post->getBlog()) {
+ $nav->appendChild(
+ id(new AphrontErrorView())
+ ->setSeverity(AphrontErrorView::SEVERITY_WARNING)
+ ->setTitle(pht('Not On A Blog'))
+ ->appendChild(
+ pht('This post is not associated with a blog (the blog may have '.
+ 'been deleted). Use "Move Post" to move it to a new blog.')));
}
$this->loadHandles(
array(
$post->getBlogPHID(),
$post->getBloggerPHID(),
));
- $nav = $this->renderSideNavFilterView(null);
-
- $header = id(new PhabricatorHeaderView())->setHeader($post->getTitle());
-
$actions = $this->renderActions($post, $user);
$properties = $this->renderProperties($post, $user);
$nav->appendChild(
array(
- $header,
$actions,
$properties,
));
return $this->buildApplicationPage(
$nav,
array(
'title' => $post->getTitle(),
'device' => true,
));
}
private function renderActions(
PhamePost $post,
PhabricatorUser $user) {
$actions = id(new PhabricatorActionListView())
->setObject($post)
->setUser($user);
$can_edit = PhabricatorPolicyFilter::hasCapability(
$user,
$post,
PhabricatorPolicyCapability::CAN_EDIT);
$id = $post->getID();
$actions->addAction(
id(new PhabricatorActionView())
->setIcon('edit')
->setHref($this->getApplicationURI('post/edit/'.$id.'/'))
->setName('Edit Post')
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit));
- $blog = $post->getBlog();
- $can_view_live = $blog && !$post->isDraft();
-
- if ($can_view_live) {
- $live_uri = 'live/'.$blog->getID().'/post/'.$post->getPhameTitle();
- } else {
- $live_uri = 'post/notlive/'.$post->getID().'/';
- }
- $live_uri = $this->getApplicationURI($live_uri);
-
$actions->addAction(
id(new PhabricatorActionView())
- ->setIcon('world')
- ->setHref($live_uri)
- ->setName(pht('View Live'))
- ->setDisabled(!$can_view_live)
- ->setWorkflow(!$can_view_live));
+ ->setIcon('move')
+ ->setHref($this->getApplicationURI('post/move/'.$id.'/'))
+ ->setName('Move Post')
+ ->setDisabled(!$can_edit)
+ ->setWorkflow(!$can_edit));
if ($post->isDraft()) {
$actions->addAction(
id(new PhabricatorActionView())
- ->setIcon('world')
+ ->setIcon('preview')
->setHref($this->getApplicationURI('post/publish/'.$id.'/'))
->setName(pht('Preview / Publish')));
} else {
$actions->addAction(
id(new PhabricatorActionView())
- ->setIcon('delete')
+ ->setIcon('unpublish')
->setHref($this->getApplicationURI('post/unpublish/'.$id.'/'))
->setName(pht('Unpublish'))
->setWorkflow(true));
}
$actions->addAction(
id(new PhabricatorActionView())
->setIcon('delete')
->setHref($this->getApplicationURI('post/delete/'.$id.'/'))
->setName('Delete Post')
->setDisabled(!$can_edit)
->setWorkflow(true));
+ $blog = $post->getBlog();
+ $can_view_live = $blog && !$post->isDraft();
+
+ if ($can_view_live) {
+ $live_uri = 'live/'.$blog->getID().'/post/'.$post->getPhameTitle();
+ } else {
+ $live_uri = 'post/notlive/'.$post->getID().'/';
+ }
+ $live_uri = $this->getApplicationURI($live_uri);
+
+ $actions->addAction(
+ id(new PhabricatorActionView())
+ ->setIcon('world')
+ ->setHref($live_uri)
+ ->setName(pht('View Live'))
+ ->setDisabled(!$can_view_live)
+ ->setWorkflow(!$can_view_live));
+
return $actions;
}
private function renderProperties(
PhamePost $post,
PhabricatorUser $user) {
$properties = new PhabricatorPropertyListView();
$descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions(
$user,
$post);
$properties->addProperty(
pht('Blog'),
$post->getBlogPHID()
? $this->getHandle($post->getBlogPHID())->renderLink()
: null);
$properties->addProperty(
pht('Blogger'),
$this->getHandle($post->getBloggerPHID())->renderLink());
$properties->addProperty(
pht('Visible To'),
$descriptions[PhabricatorPolicyCapability::CAN_VIEW]);
$properties->addProperty(
pht('Published'),
$post->isDraft()
? pht('Draft')
: phabricator_datetime($post->getDatePublished(), $user));
$engine = id(new PhabricatorMarkupEngine())
->setViewer($user)
->addObject($post, PhamePost::MARKUP_FIELD_BODY)
->process();
$properties->addTextContent(
'<div class="phabricator-remarkup">'.
$engine->getOutput($post, PhamePost::MARKUP_FIELD_BODY).
'</div>');
return $properties;
}
}
diff --git a/src/view/form/AphrontErrorView.php b/src/view/form/AphrontErrorView.php
index f68dc129cd..dce3e9a974 100644
--- a/src/view/form/AphrontErrorView.php
+++ b/src/view/form/AphrontErrorView.php
@@ -1,108 +1,107 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
final class AphrontErrorView extends AphrontView {
const SEVERITY_ERROR = 'error';
const SEVERITY_WARNING = 'warning';
const SEVERITY_NOTICE = 'notice';
const SEVERITY_NODATA = 'nodata';
private $title;
private $errors;
private $severity;
private $id;
public function setTitle($title) {
$this->title = $title;
return $this;
}
public function setSeverity($severity) {
$this->severity = $severity;
return $this;
}
public function setErrors(array $errors) {
$this->errors = $errors;
return $this;
}
public function setID($id) {
$this->id = $id;
return $this;
}
final public function render() {
require_celerity_resource('aphront-error-view-css');
$errors = $this->errors;
if ($errors) {
$list = array();
foreach ($errors as $error) {
$list[] = phutil_render_tag(
'li',
array(),
phutil_escape_html($error));
}
$list = phutil_render_tag(
'ul',
array(
'class' => 'aphront-error-view-list',
),
implode("\n", $list));
} else {
$list = null;
}
$title = $this->title;
if (strlen($title)) {
$title = phutil_render_tag(
'h1',
array(
'class' => 'aphront-error-view-head',
),
phutil_escape_html($title));
} else {
$title = null;
}
$this->severity = nonempty($this->severity, self::SEVERITY_ERROR);
$more_classes = array();
$more_classes[] = 'aphront-error-severity-'.$this->severity;
$more_classes = implode(' ', $more_classes);
- return
+ return phutil_render_tag(
+ 'div',
+ array(
+ 'id' => $this->id,
+ 'class' => 'aphront-error-view '.$more_classes,
+ ),
+ $title.
phutil_render_tag(
'div',
array(
- 'id' => $this->id,
- 'class' => 'aphront-error-view '.$more_classes,
+ 'class' => 'aphront-error-view-body',
),
- $title.
- phutil_render_tag(
- 'div',
- array(
- 'class' => 'aphront-error-view-body',
- ),
- $this->renderChildren().
- $list));
+ $this->renderChildren().
+ $list));
}
}
diff --git a/webroot/rsrc/css/aphront/error-view.css b/webroot/rsrc/css/aphront/error-view.css
index 02056f45cf..21f6e36156 100644
--- a/webroot/rsrc/css/aphront/error-view.css
+++ b/webroot/rsrc/css/aphront/error-view.css
@@ -1,68 +1,69 @@
/**
* @provides aphront-error-view-css
*/
.aphront-error-view {
margin: 1em 2%;
box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.1);
border-style: solid;
border-width: 1px;
}
.aphront-error-view-body {
padding: 0.5em 1em;
font-size: 12px;
line-height: 1.6em;
}
.aphront-error-view-head {
font-size: 13px;
padding: 0.5em 1em;
font-weight: bold;
color: #333333;
}
.aphront-error-view-list {
margin: 0.2em 0 0.2em 2em;
list-style: disc;
}
.aphront-error-severity-error {
border-color: #aa0000;
background: #fff3f3;
}
.aphront-error-severity-error .aphront-error-view-head {
background: #ffe3e3;
}
.aphront-error-severity-warning {
border-color: #888800;
background: #ffffee;
}
.aphront-error-severity-warning .aphront-error-view-head {
background: #ffffcc;
}
.aphront-error-severity-notice {
border-color: #000088;
background: #f3f3ff;
}
.aphront-error-severity-notice .aphront-error-view-head {
background: #e3e3ff;
}
.aphront-error-severity-nodata {
border-color: #dfdfdf;
background: #f3f3f3;
color: #666666;
box-shadow: 0px 0px 0px #000;
}
.aphront-error-severity-nodata .aphront-error-view-head {
background: #e3e3e3;
}
+
diff --git a/webroot/rsrc/css/autosprite.css b/webroot/rsrc/css/autosprite.css
index e26de1e87e..5b93e88883 100644
--- a/webroot/rsrc/css/autosprite.css
+++ b/webroot/rsrc/css/autosprite.css
@@ -1,797 +1,809 @@
/**
* @provides autosprite-css
* @generated
*/
.autosprite {
background-image: url(/rsrc/image/autosprite.png);
background-repeat: no-repeat;
}
.main-menu-item-icon-help {
background-position: 0px 0px;
}
.main-menu-item-icon-help-selected {
background-position: 0px -27px;
}
.main-menu-item-icon-help:hover {
background-position: 0px -54px;
}
.main-menu-item-icon-settings {
background-position: 0px -81px;
}
.main-menu-item-icon-settings-selected {
background-position: 0px -108px;
}
.main-menu-item-icon-settings:hover {
background-position: 0px -135px;
}
.main-menu-item-icon-logout {
background-position: 0px -162px;
}
.main-menu-item-icon-logout-selected {
background-position: 0px -189px;
}
.main-menu-item-icon-logout:hover {
background-position: 0px -216px;
}
.main-menu-item-icon-notifications {
background-position: 0px -243px;
}
.main-menu-item-icon-notifications-selected {
background-position: 0px -270px;
}
.main-menu-item-icon-notifications:hover {
background-position: 0px -297px;
}
.main-menu-item-icon-task {
background-position: 0px -324px;
}
.main-menu-item-icon-task-selected {
background-position: 0px -351px;
}
.main-menu-item-icon-task:hover {
background-position: 0px -378px;
}
.app-differential-large {
background-position: 0px -405px;
}
.device-desktop .phabricator-application-launch-container:hover .app-differential-large /* hover */ {
background-position: 0px -466px;
}
.app-differential {
background-position: 0px -527px;
}
.device-desktop .app-differential:hover {
background-position: 0px -558px;
}
.app-differential-selected {
background-position: 0px -589px;
}
.app-fact-large {
background-position: 0px -620px;
}
.device-desktop .phabricator-application-launch-container:hover .app-fact-large /* hover */ {
background-position: 0px -681px;
}
.app-fact {
background-position: 0px -742px;
}
.device-desktop .app-fact:hover {
background-position: 0px -773px;
}
.app-fact-selected {
background-position: 0px -804px;
}
.app-mail-large {
background-position: 0px -835px;
}
.device-desktop .phabricator-application-launch-container:hover .app-mail-large /* hover */ {
background-position: 0px -896px;
}
.app-mail {
background-position: 0px -957px;
}
.device-desktop .app-mail:hover {
background-position: 0px -988px;
}
.app-mail-selected {
background-position: 0px -1019px;
}
.app-diffusion-large {
background-position: 0px -1050px;
}
.device-desktop .phabricator-application-launch-container:hover .app-diffusion-large /* hover */ {
background-position: 0px -1111px;
}
.app-diffusion {
background-position: 0px -1172px;
}
.device-desktop .app-diffusion:hover {
background-position: 0px -1203px;
}
.app-diffusion-selected {
background-position: 0px -1234px;
}
.app-slowvote-large {
background-position: 0px -1265px;
}
.device-desktop .phabricator-application-launch-container:hover .app-slowvote-large /* hover */ {
background-position: 0px -1326px;
}
.app-slowvote {
background-position: 0px -1387px;
}
.device-desktop .app-slowvote:hover {
background-position: 0px -1418px;
}
.app-slowvote-selected {
background-position: 0px -1449px;
}
.app-phriction-large {
background-position: 0px -1480px;
}
.device-desktop .phabricator-application-launch-container:hover .app-phriction-large /* hover */ {
background-position: 0px -1541px;
}
.app-phriction {
background-position: 0px -1602px;
}
.device-desktop .app-phriction:hover {
background-position: 0px -1633px;
}
.app-phriction-selected {
background-position: 0px -1664px;
}
.app-maniphest-large {
background-position: 0px -1695px;
}
.device-desktop .phabricator-application-launch-container:hover .app-maniphest-large /* hover */ {
background-position: 0px -1756px;
}
.app-maniphest {
background-position: 0px -1817px;
}
.device-desktop .app-maniphest:hover {
background-position: 0px -1848px;
}
.app-maniphest-selected {
background-position: 0px -1879px;
}
.app-flags-large {
background-position: 0px -1910px;
}
.device-desktop .phabricator-application-launch-container:hover .app-flags-large /* hover */ {
background-position: 0px -1971px;
}
.app-flags {
background-position: 0px -2032px;
}
.device-desktop .app-flags:hover {
background-position: 0px -2063px;
}
.app-flags-selected {
background-position: 0px -2094px;
}
.app-settings-large {
background-position: 0px -2125px;
}
.device-desktop .phabricator-application-launch-container:hover .app-settings-large /* hover */ {
background-position: 0px -2186px;
}
.app-settings {
background-position: 0px -2247px;
}
.device-desktop .app-settings:hover {
background-position: 0px -2278px;
}
.app-settings-selected {
background-position: 0px -2309px;
}
.app-applications-large {
background-position: 0px -2340px;
}
.device-desktop .phabricator-application-launch-container:hover .app-applications-large /* hover */ {
background-position: 0px -2401px;
}
.app-applications {
background-position: 0px -2462px;
}
.device-desktop .app-applications:hover {
background-position: 0px -2493px;
}
.app-applications-selected {
background-position: 0px -2524px;
}
.app-default-large {
background-position: 0px -2555px;
}
.device-desktop .phabricator-application-launch-container:hover .app-default-large /* hover */ {
background-position: 0px -2616px;
}
.app-default {
background-position: 0px -2677px;
}
.device-desktop .app-default:hover {
background-position: 0px -2708px;
}
.app-default-selected {
background-position: 0px -2739px;
}
.app-people-large {
background-position: 0px -2770px;
}
.device-desktop .phabricator-application-launch-container:hover .app-people-large /* hover */ {
background-position: 0px -2831px;
}
.app-people {
background-position: 0px -2892px;
}
.device-desktop .app-people:hover {
background-position: 0px -2923px;
}
.app-people-selected {
background-position: 0px -2954px;
}
.app-ponder-large {
background-position: 0px -2985px;
}
.device-desktop .phabricator-application-launch-container:hover .app-ponder-large /* hover */ {
background-position: 0px -3046px;
}
.app-ponder {
background-position: 0px -3107px;
}
.device-desktop .app-ponder:hover {
background-position: 0px -3138px;
}
.app-ponder-selected {
background-position: 0px -3169px;
}
.app-calendar-large {
background-position: 0px -3200px;
}
.device-desktop .phabricator-application-launch-container:hover .app-calendar-large /* hover */ {
background-position: 0px -3261px;
}
.app-calendar {
background-position: 0px -3322px;
}
.device-desktop .app-calendar:hover {
background-position: 0px -3353px;
}
.app-calendar-selected {
background-position: 0px -3384px;
}
.app-files-large {
background-position: 0px -3415px;
}
.device-desktop .phabricator-application-launch-container:hover .app-files-large /* hover */ {
background-position: 0px -3476px;
}
.app-files {
background-position: 0px -3537px;
}
.device-desktop .app-files:hover {
background-position: 0px -3568px;
}
.app-files-selected {
background-position: 0px -3599px;
}
.app-projects-large {
background-position: 0px -3630px;
}
.device-desktop .phabricator-application-launch-container:hover .app-projects-large /* hover */ {
background-position: 0px -3691px;
}
.app-projects {
background-position: 0px -3752px;
}
.device-desktop .app-projects:hover {
background-position: 0px -3783px;
}
.app-projects-selected {
background-position: 0px -3814px;
}
.app-daemons-large {
background-position: 0px -3845px;
}
.device-desktop .phabricator-application-launch-container:hover .app-daemons-large /* hover */ {
background-position: 0px -3906px;
}
.app-daemons {
background-position: 0px -3967px;
}
.device-desktop .app-daemons:hover {
background-position: 0px -3998px;
}
.app-daemons-selected {
background-position: 0px -4029px;
}
.app-herald-large {
background-position: 0px -4060px;
}
.device-desktop .phabricator-application-launch-container:hover .app-herald-large /* hover */ {
background-position: 0px -4121px;
}
.app-herald {
background-position: 0px -4182px;
}
.device-desktop .app-herald:hover {
background-position: 0px -4213px;
}
.app-herald-selected {
background-position: 0px -4244px;
}
.app-countdown-large {
background-position: 0px -4275px;
}
.device-desktop .phabricator-application-launch-container:hover .app-countdown-large /* hover */ {
background-position: 0px -4336px;
}
.app-countdown {
background-position: 0px -4397px;
}
.device-desktop .app-countdown:hover {
background-position: 0px -4428px;
}
.app-countdown-selected {
background-position: 0px -4459px;
}
.app-conduit-large {
background-position: 0px -4490px;
}
.device-desktop .phabricator-application-launch-container:hover .app-conduit-large /* hover */ {
background-position: 0px -4551px;
}
.app-conduit {
background-position: 0px -4612px;
}
.device-desktop .app-conduit:hover {
background-position: 0px -4643px;
}
.app-conduit-selected {
background-position: 0px -4674px;
}
.app-feed-large {
background-position: 0px -4705px;
}
.device-desktop .phabricator-application-launch-container:hover .app-feed-large /* hover */ {
background-position: 0px -4766px;
}
.app-feed {
background-position: 0px -4827px;
}
.device-desktop .app-feed:hover {
background-position: 0px -4858px;
}
.app-feed-selected {
background-position: 0px -4889px;
}
.app-paste-large {
background-position: 0px -4920px;
}
.device-desktop .phabricator-application-launch-container:hover .app-paste-large /* hover */ {
background-position: 0px -4981px;
}
.app-paste {
background-position: 0px -5042px;
}
.device-desktop .app-paste:hover {
background-position: 0px -5073px;
}
.app-paste-selected {
background-position: 0px -5104px;
}
.app-audit-large {
background-position: 0px -5135px;
}
.device-desktop .phabricator-application-launch-container:hover .app-audit-large /* hover */ {
background-position: 0px -5196px;
}
.app-audit {
background-position: 0px -5257px;
}
.device-desktop .app-audit:hover {
background-position: 0px -5288px;
}
.app-audit-selected {
background-position: 0px -5319px;
}
.app-uiexample-large {
background-position: 0px -5350px;
}
.device-desktop .phabricator-application-launch-container:hover .app-uiexample-large /* hover */ {
background-position: 0px -5411px;
}
.app-uiexample {
background-position: 0px -5472px;
}
.device-desktop .app-uiexample:hover {
background-position: 0px -5503px;
}
.app-uiexample-selected {
background-position: 0px -5534px;
}
.app-phpast-large {
background-position: 0px -5565px;
}
.device-desktop .phabricator-application-launch-container:hover .app-phpast-large /* hover */ {
background-position: 0px -5626px;
}
.app-phpast {
background-position: 0px -5687px;
}
.device-desktop .app-phpast:hover {
background-position: 0px -5718px;
}
.app-phpast-selected {
background-position: 0px -5749px;
}
.app-owners-large {
background-position: 0px -5780px;
}
.device-desktop .phabricator-application-launch-container:hover .app-owners-large /* hover */ {
background-position: 0px -5841px;
}
.app-owners {
background-position: 0px -5902px;
}
.device-desktop .app-owners:hover {
background-position: 0px -5933px;
}
.app-owners-selected {
background-position: 0px -5964px;
}
.app-phid-large {
background-position: 0px -5995px;
}
.device-desktop .phabricator-application-launch-container:hover .app-phid-large /* hover */ {
background-position: 0px -6056px;
}
.app-phid {
background-position: 0px -6117px;
}
.device-desktop .app-phid:hover {
background-position: 0px -6148px;
}
.app-phid-selected {
background-position: 0px -6179px;
}
.app-diviner-large {
background-position: 0px -6210px;
}
.device-desktop .phabricator-application-launch-container:hover .app-diviner-large /* hover */ {
background-position: 0px -6271px;
}
.app-diviner {
background-position: 0px -6332px;
}
.device-desktop .app-diviner:hover {
background-position: 0px -6363px;
}
.app-diviner-selected {
background-position: 0px -6394px;
}
.app-repositories-large {
background-position: 0px -6425px;
}
.device-desktop .phabricator-application-launch-container:hover .app-repositories-large /* hover */ {
background-position: 0px -6486px;
}
.app-repositories {
background-position: 0px -6547px;
}
.device-desktop .app-repositories:hover {
background-position: 0px -6578px;
}
.app-repositories-selected {
background-position: 0px -6609px;
}
.app-phame-large {
background-position: 0px -6640px;
}
.device-desktop .phabricator-application-launch-container:hover .app-phame-large /* hover */ {
background-position: 0px -6701px;
}
.app-phame {
background-position: 0px -6762px;
}
.device-desktop .app-phame:hover {
background-position: 0px -6793px;
}
.app-phame-selected {
background-position: 0px -6824px;
}
.app-macro-large {
background-position: 0px -6855px;
}
.device-desktop .phabricator-application-launch-container:hover .app-macro-large /* hover */ {
background-position: 0px -6916px;
}
.app-macro {
background-position: 0px -6977px;
}
.device-desktop .app-macro:hover {
background-position: 0px -7008px;
}
.app-macro-selected {
background-position: 0px -7039px;
}
.action-file {
background-position: 0px -7070px;
}
.action-fork {
background-position: 0px -7087px;
}
.action-edit {
background-position: 0px -7104px;
}
.action-flag-0 {
background-position: 0px -7121px;
}
.action-flag-1 {
background-position: 0px -7138px;
}
.action-flag-2 {
background-position: 0px -7155px;
}
.action-flag-3 {
background-position: 0px -7172px;
}
.action-flag-4 {
background-position: 0px -7189px;
}
.action-flag-5 {
background-position: 0px -7206px;
}
.action-flag-6 {
background-position: 0px -7223px;
}
.action-flag-7 {
background-position: 0px -7240px;
}
.action-flag-ghost {
background-position: 0px -7257px;
}
.action-subscribe-auto {
background-position: 0px -7274px;
}
.action-subscribe-add {
background-position: 0px -7291px;
}
.action-subscribe-delete {
background-position: 0px -7308px;
}
.action-new {
background-position: 0px -7325px;
}
.action-world {
background-position: 0px -7342px;
}
.action-delete {
background-position: 0px -7359px;
}
-.remarkup-assist-b {
+.action-move {
background-position: 0px -7376px;
}
+.action-preview {
+ background-position: 0px -7393px;
+}
+
+.action-unpublish {
+ background-position: 0px -7410px;
+}
+
+.remarkup-assist-b {
+ background-position: 0px -7427px;
+}
+
.remarkup-assist-code {
- background-position: 0px -7391px;
+ background-position: 0px -7442px;
}
.remarkup-assist-i {
- background-position: 0px -7406px;
+ background-position: 0px -7457px;
}
.remarkup-assist-image {
- background-position: 0px -7421px;
+ background-position: 0px -7472px;
}
.remarkup-assist-ol {
- background-position: 0px -7436px;
+ background-position: 0px -7487px;
}
.remarkup-assist-tag {
- background-position: 0px -7451px;
+ background-position: 0px -7502px;
}
.remarkup-assist-tt {
- background-position: 0px -7466px;
+ background-position: 0px -7517px;
}
.remarkup-assist-ul {
- background-position: 0px -7481px;
+ background-position: 0px -7532px;
}
.remarkup-assist-help {
- background-position: 0px -7496px;
+ background-position: 0px -7547px;
}
diff --git a/webroot/rsrc/css/layout/phabricator-action-list-view.css b/webroot/rsrc/css/layout/phabricator-action-list-view.css
index 80083e448a..a8d7ce03d2 100644
--- a/webroot/rsrc/css/layout/phabricator-action-list-view.css
+++ b/webroot/rsrc/css/layout/phabricator-action-list-view.css
@@ -1,80 +1,80 @@
/**
* @provides phabricator-action-list-view-css
*/
.phabricator-action-list-view {
background: #ffffff;
}
.device-desktop .phabricator-action-list-view {
border: 1px solid #dcdcdc;
padding: .5em 0;
float: right;
- margin-top: -30px;
+ margin-top: 0px;
margin-right: 1%;
width: 20%;
border-radius: 2px;
font-size: 12px;
box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.10);
}
.device-tablet .phabricator-action-list-view,
.device-phone .phabricator-action-list-view {
background: #f3f3f3;
border-top: 1px solid #dcdcdc;
padding: .5em 0;
}
.phabricator-action-view {
padding: 2px 0;
position: relative;
}
.phabricator-action-view button.phabricator-action-view-item {
border: none;
background: transparent;
box-shadow: none;
outline: 0;
box-shadow: 0;
padding: 0;
margin: 0;
font-weight: normal;
color: #3b5998;
width: 100%;
text-align: left;
}
.phabricator-action-view button.phabricator-action-view-item,
.phabricator-action-view-item {
line-height: 20px;
padding-left: 34px;
display: block;
font-size: 12px;
}
.phabricator-action-view-icon {
width: 16px;
height: 16px;
position: absolute;
top: 4px;
left: 12px;
}
.device-desktop .phabricator-action-view-item:hover {
background-color: #3875d7;
color: #ffffff;
text-decoration: none;
}
.phabricator-action-view-disabled .phabricator-action-view-item,
.phabricator-action-view-disabled button.phabricator-action-view-item {
color: #888888;
}
.phabricator-action-view-disabled .phabricator-action-view-item:hover,
.phabricator-action-view-disabled button.phabricator-action-view-item:hover {
background-color: #dfdfdf;
color: #888888;
}
diff --git a/webroot/rsrc/css/layout/phabricator-property-list-view.css b/webroot/rsrc/css/layout/phabricator-property-list-view.css
index 22f3affe7a..dec6656600 100644
--- a/webroot/rsrc/css/layout/phabricator-property-list-view.css
+++ b/webroot/rsrc/css/layout/phabricator-property-list-view.css
@@ -1,68 +1,92 @@
/**
* @provides phabricator-property-list-view-css
*/
.phabricator-property-list-view {
border-color: #dbdbdb;
border-style: solid;
border-width: 1px 0;
background-color: #f9f9f9;
}
.phabriator-property-list-view-end {
clear: both;
}
.device-desktop .phabricator-property-list-view {
padding: 1em 0 0.75em;
}
.device-tablet .phabricator-property-list-view,
.device-phone .phabricator-property-list-view {
padding: .5em;
}
.phabricator-property-key {
color: #333333;
font-weight: bold;
}
.device-desktop .phabricator-property-key {
width: 12%;
margin-left: 1%;
text-align: right;
float: left;
clear: left;
margin-bottom: .5em;
}
.device-tablet .phabricator-property-key,
.device-phone .phabricator-property-key {
padding-left: .5em;
}
.phabricator-property-value {
color: #333333;
}
.device-desktop .phabricator-property-value {
width: 53%;
margin-left: 1%;
float: left;
margin-bottom: .5em;
}
.device-tablet .phabricator-property-value,
.device-phone .phabricator-property-value {
padding-left: 1.5em;
margin-bottom: .5em;
}
.phabricator-property-list-content {
background: #fdfdfd;
border-bottom: 1px solid #dbdbdb;
}
.phabricator-property-list-text-content {
padding: 12px 18px;
}
+
+/* When we follow an action list view on the Desktop, move down 30px so the
+ action list can start slightly above the property list. This is an unusual
+ case where we have something between the header and the action/property
+ lists and we want to give it space. */
+.device-desktop .phabricator-action-list-view +
+ .phabricator-property-list-view {
+ clear: left;
+ margin-top: 30px;
+}
+
+
+/* In the common case where we immediately follow a header, move back up 30px
+ so we snuggle next to the header. */
+.device-desktop .phabricator-header-view
+ + .phabricator-action-list-view {
+ margin-top: -30px;
+}
+
+.device-desktop .phabricator-header-view
+ + .phabricator-action-list-view
+ + .phabricator-property-list-view {
+ margin-top: 0px;
+}
diff --git a/webroot/rsrc/image/autosprite.png b/webroot/rsrc/image/autosprite.png
index 35b9978462..89a7ff31ad 100644
Binary files a/webroot/rsrc/image/autosprite.png and b/webroot/rsrc/image/autosprite.png differ

File Metadata

Mime Type
text/x-diff
Expires
Fri, Nov 14, 8:41 AM (1 d, 8 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
336899
Default Alt Text
(62 KB)

Event Timeline