Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/celerity/CelerityStaticResourceResponse.php b/src/applications/celerity/CelerityStaticResourceResponse.php
index f81b8d5957..7db6c2741b 100644
--- a/src/applications/celerity/CelerityStaticResourceResponse.php
+++ b/src/applications/celerity/CelerityStaticResourceResponse.php
@@ -1,337 +1,347 @@
<?php
/**
* Tracks and resolves dependencies the page declares with
* @{function:require_celerity_resource}, and then builds appropriate HTML or
* Ajax responses.
*/
final class CelerityStaticResourceResponse extends Phobject {
private $symbols = array();
private $needsResolve = true;
private $resolved;
private $packaged;
private $metadata = array();
private $metadataBlock = 0;
+ private $metadataLocked;
private $behaviors = array();
private $hasRendered = array();
private $postprocessorKey;
public function __construct() {
if (isset($_REQUEST['__metablock__'])) {
$this->metadataBlock = (int)$_REQUEST['__metablock__'];
}
}
public function addMetadata($metadata) {
+ if ($this->metadataLocked) {
+ throw new Exception(
+ pht(
+ 'Attempting to add more metadata after metadata has been '.
+ 'locked.'));
+ }
+
$id = count($this->metadata);
$this->metadata[$id] = $metadata;
return $this->metadataBlock.'_'.$id;
}
public function getMetadataBlock() {
return $this->metadataBlock;
}
public function setPostprocessorKey($postprocessor_key) {
$this->postprocessorKey = $postprocessor_key;
return $this;
}
public function getPostprocessorKey() {
return $this->postprocessorKey;
}
/**
* Register a behavior for initialization.
*
* NOTE: If `$config` is empty, a behavior will execute only once even if it
* is initialized multiple times. If `$config` is nonempty, the behavior will
* be invoked once for each configuration.
*/
public function initBehavior(
$behavior,
array $config = array(),
$source_name = null) {
$this->requireResource('javelin-behavior-'.$behavior, $source_name);
if (empty($this->behaviors[$behavior])) {
$this->behaviors[$behavior] = array();
}
if ($config) {
$this->behaviors[$behavior][] = $config;
}
return $this;
}
public function requireResource($symbol, $source_name) {
if (isset($this->symbols[$source_name][$symbol])) {
return $this;
}
// Verify that the resource exists.
$map = CelerityResourceMap::getNamedInstance($source_name);
$name = $map->getResourceNameForSymbol($symbol);
if ($name === null) {
throw new Exception(
pht(
'No resource with symbol "%s" exists in source "%s"!',
$symbol,
$source_name));
}
$this->symbols[$source_name][$symbol] = true;
$this->needsResolve = true;
return $this;
}
private function resolveResources() {
if ($this->needsResolve) {
$this->packaged = array();
foreach ($this->symbols as $source_name => $symbols_map) {
$symbols = array_keys($symbols_map);
$map = CelerityResourceMap::getNamedInstance($source_name);
$packaged = $map->getPackagedNamesForSymbols($symbols);
$this->packaged[$source_name] = $packaged;
}
$this->needsResolve = false;
}
return $this;
}
public function renderSingleResource($symbol, $source_name) {
$map = CelerityResourceMap::getNamedInstance($source_name);
$packaged = $map->getPackagedNamesForSymbols(array($symbol));
return $this->renderPackagedResources($map, $packaged);
}
public function renderResourcesOfType($type) {
$this->resolveResources();
$result = array();
foreach ($this->packaged as $source_name => $resource_names) {
$map = CelerityResourceMap::getNamedInstance($source_name);
$resources_of_type = array();
foreach ($resource_names as $resource_name) {
$resource_type = $map->getResourceTypeForName($resource_name);
if ($resource_type == $type) {
$resources_of_type[] = $resource_name;
}
}
$result[] = $this->renderPackagedResources($map, $resources_of_type);
}
return phutil_implode_html('', $result);
}
private function renderPackagedResources(
CelerityResourceMap $map,
array $resources) {
$output = array();
foreach ($resources as $name) {
if (isset($this->hasRendered[$name])) {
continue;
}
$this->hasRendered[$name] = true;
$output[] = $this->renderResource($map, $name);
}
return $output;
}
private function renderResource(
CelerityResourceMap $map,
$name) {
$uri = $this->getURI($map, $name);
$type = $map->getResourceTypeForName($name);
$multimeter = MultimeterControl::getInstance();
if ($multimeter) {
$event_type = MultimeterEvent::TYPE_STATIC_RESOURCE;
$multimeter->newEvent($event_type, 'rsrc.'.$name, 1);
}
switch ($type) {
case 'css':
return phutil_tag(
'link',
array(
'rel' => 'stylesheet',
'type' => 'text/css',
'href' => $uri,
));
case 'js':
return phutil_tag(
'script',
array(
'type' => 'text/javascript',
'src' => $uri,
),
'');
}
throw new Exception(
pht(
'Unable to render resource "%s", which has unknown type "%s".',
$name,
$type));
}
public function renderHTMLFooter() {
+ $this->metadataLocked = true;
+
$data = array();
if ($this->metadata) {
$json_metadata = AphrontResponse::encodeJSONForHTTPResponse(
$this->metadata);
$this->metadata = array();
} else {
$json_metadata = '{}';
}
// Even if there is no metadata on the page, Javelin uses the mergeData()
// call to start dispatching the event queue.
$data[] = 'JX.Stratcom.mergeData('.$this->metadataBlock.', '.
$json_metadata.');';
$onload = array();
if ($this->behaviors) {
$behaviors = $this->behaviors;
$this->behaviors = array();
$higher_priority_names = array(
'refresh-csrf',
'aphront-basic-tokenizer',
'dark-console',
'history-install',
);
$higher_priority_behaviors = array_select_keys(
$behaviors,
$higher_priority_names);
foreach ($higher_priority_names as $name) {
unset($behaviors[$name]);
}
$behavior_groups = array(
$higher_priority_behaviors,
$behaviors,
);
foreach ($behavior_groups as $group) {
if (!$group) {
continue;
}
$group_json = AphrontResponse::encodeJSONForHTTPResponse(
$group);
$onload[] = 'JX.initBehaviors('.$group_json.')';
}
}
if ($onload) {
foreach ($onload as $func) {
$data[] = 'JX.onload(function(){'.$func.'});';
}
}
if ($data) {
$data = implode("\n", $data);
return self::renderInlineScript($data);
} else {
return '';
}
}
public static function renderInlineScript($data) {
if (stripos($data, '</script>') !== false) {
throw new Exception(
pht(
'Literal %s is not allowed inside inline script.',
'</script>'));
}
if (strpos($data, '<!') !== false) {
throw new Exception(
pht(
'Literal %s is not allowed inside inline script.',
'<!'));
}
// We don't use <![CDATA[ ]]> because it is ignored by HTML parsers. We
// would need to send the document with XHTML content type.
return phutil_tag(
'script',
array('type' => 'text/javascript'),
phutil_safe_html($data));
}
public function buildAjaxResponse($payload, $error = null) {
$response = array(
'error' => $error,
'payload' => $payload,
);
if ($this->metadata) {
$response['javelin_metadata'] = $this->metadata;
$this->metadata = array();
}
if ($this->behaviors) {
$response['javelin_behaviors'] = $this->behaviors;
$this->behaviors = array();
}
$this->resolveResources();
$resources = array();
foreach ($this->packaged as $source_name => $resource_names) {
$map = CelerityResourceMap::getNamedInstance($source_name);
foreach ($resource_names as $resource_name) {
$resources[] = $this->getURI($map, $resource_name);
}
}
if ($resources) {
$response['javelin_resources'] = $resources;
}
return $response;
}
public function getURI(
CelerityResourceMap $map,
$name,
$use_primary_domain = false) {
$uri = $map->getURIForName($name);
// If we have a postprocessor selected, add it to the URI.
$postprocessor_key = $this->getPostprocessorKey();
if ($postprocessor_key) {
$uri = preg_replace('@^/res/@', '/res/'.$postprocessor_key.'X/', $uri);
}
// In developer mode, we dump file modification times into the URI. When a
// page is reloaded in the browser, any resources brought in by Ajax calls
// do not trigger revalidation, so without this it's very difficult to get
// changes to Ajaxed-in CSS to work (you must clear your cache or rerun
// the map script). In production, we can assume the map script gets run
// after changes, and safely skip this.
if (PhabricatorEnv::getEnvConfig('phabricator.developer-mode')) {
$mtime = $map->getModifiedTimeForName($name);
$uri = preg_replace('@^/res/@', '/res/'.$mtime.'T/', $uri);
}
if ($use_primary_domain) {
return PhabricatorEnv::getURI($uri);
} else {
return PhabricatorEnv::getCDNURI($uri);
}
}
}
diff --git a/src/view/layout/PhabricatorActionListView.php b/src/view/layout/PhabricatorActionListView.php
index 4965f02793..5c3facbf42 100644
--- a/src/view/layout/PhabricatorActionListView.php
+++ b/src/view/layout/PhabricatorActionListView.php
@@ -1,57 +1,63 @@
<?php
final class PhabricatorActionListView extends AphrontView {
private $actions = array();
private $object;
private $id = null;
public function setObject(PhabricatorLiskDAO $object) {
$this->object = $object;
return $this;
}
public function addAction(PhabricatorActionView $view) {
$this->actions[] = $view;
return $this;
}
public function setID($id) {
$this->id = $id;
return $this;
}
public function render() {
$viewer = $this->getViewer();
$event = new PhabricatorEvent(
PhabricatorEventType::TYPE_UI_DIDRENDERACTIONS,
array(
'object' => $this->object,
'actions' => $this->actions,
));
$event->setUser($viewer);
PhutilEventEngine::dispatchEvent($event);
$actions = $event->getValue('actions');
if (!$actions) {
return null;
}
foreach ($actions as $action) {
$action->setViewer($viewer);
}
require_celerity_resource('phabricator-action-list-view-css');
return phutil_tag(
'ul',
array(
'class' => 'phabricator-action-list-view',
'id' => $this->id,
),
$actions);
}
+ public function getDropdownMenuMetadata() {
+ return array(
+ 'items' => (string)hsprintf('%s', $this),
+ );
+ }
+
}
diff --git a/src/view/phui/PHUIButtonView.php b/src/view/phui/PHUIButtonView.php
index 9b9d4f0293..f9266a170a 100644
--- a/src/view/phui/PHUIButtonView.php
+++ b/src/view/phui/PHUIButtonView.php
@@ -1,195 +1,192 @@
<?php
final class PHUIButtonView extends AphrontTagView {
const GREEN = 'green';
const GREY = 'grey';
const DISABLED = 'disabled';
const SIMPLE = 'simple';
const SIMPLE_YELLOW = 'simple simple-yellow';
const SIMPLE_GREY = 'simple simple-grey';
const SIMPLE_BLUE = 'simple simple-blue';
const SMALL = 'small';
const BIG = 'big';
private $size;
private $text;
private $subtext;
private $color;
private $tag = 'button';
private $dropdown;
private $icon;
private $iconFirst;
private $href = null;
private $title = null;
private $disabled;
private $name;
private $tooltip;
public function setName($name) {
$this->name = $name;
return $this;
}
public function getName() {
return $this->name;
}
public function setText($text) {
$this->text = $text;
return $this;
}
public function setHref($href) {
$this->href = $href;
return $this;
}
public function setTitle($title) {
$this->title = $title;
return $this;
}
public function setSubtext($subtext) {
$this->subtext = $subtext;
return $this;
}
public function setColor($color) {
$this->color = $color;
return $this;
}
public function setDisabled($disabled) {
$this->disabled = $disabled;
return $this;
}
public function setTag($tag) {
$this->tag = $tag;
return $this;
}
public function setSize($size) {
$this->size = $size;
return $this;
}
public function setDropdown($dd) {
$this->dropdown = $dd;
return $this;
}
public function setTooltip($text) {
$this->tooltip = $text;
return $this;
}
public function setIcon($icon, $first = true) {
if (!($icon instanceof PHUIIconView)) {
$icon = id(new PHUIIconView())
->setIcon($icon);
}
$this->icon = $icon;
$this->iconFirst = $first;
return $this;
}
protected function getTagName() {
return $this->tag;
}
public function setDropdownMenu(PhabricatorActionListView $actions) {
Javelin::initBehavior('phui-dropdown-menu');
$this->addSigil('phui-dropdown-menu');
- $this->setMetadata(
- array(
- 'items' => $actions,
- ));
+ $this->setMetadata($actions->getDropdownMenuMetadata());
return $this;
}
protected function getTagAttributes() {
require_celerity_resource('phui-button-css');
$classes = array();
$classes[] = 'button';
if ($this->color) {
$classes[] = $this->color;
}
if ($this->size) {
$classes[] = $this->size;
}
if ($this->dropdown) {
$classes[] = 'dropdown';
}
if ($this->icon) {
$classes[] = 'has-icon';
}
if ($this->iconFirst == false) {
$classes[] = 'icon-last';
}
if ($this->disabled) {
$classes[] = 'disabled';
}
$sigil = null;
$meta = null;
if ($this->tooltip) {
Javelin::initBehavior('phabricator-tooltips');
require_celerity_resource('aphront-tooltip-css');
$sigil = 'has-tooltip';
$meta = array(
'tip' => $this->tooltip,
);
}
return array(
'class' => $classes,
'href' => $this->href,
'name' => $this->name,
'title' => $this->title,
'sigil' => $sigil,
'meta' => $meta,
);
}
protected function getTagContent() {
$icon = null;
$text = $this->text;
if ($this->icon) {
$icon = $this->icon;
$subtext = null;
if ($this->subtext) {
$subtext = phutil_tag(
'div', array('class' => 'phui-button-subtext'), $this->subtext);
}
$text = phutil_tag(
'div', array('class' => 'phui-button-text'), array($text, $subtext));
}
$caret = null;
if ($this->dropdown) {
$caret = phutil_tag('span', array('class' => 'caret'), '');
}
if ($this->iconFirst == true) {
return array($icon, $text, $caret);
} else {
return array($text, $icon);
}
}
}
diff --git a/src/view/phui/PHUIListItemView.php b/src/view/phui/PHUIListItemView.php
index 33c511c9c0..4af02e572e 100644
--- a/src/view/phui/PHUIListItemView.php
+++ b/src/view/phui/PHUIListItemView.php
@@ -1,310 +1,307 @@
<?php
final class PHUIListItemView extends AphrontTagView {
const TYPE_LINK = 'type-link';
const TYPE_SPACER = 'type-spacer';
const TYPE_LABEL = 'type-label';
const TYPE_BUTTON = 'type-button';
const TYPE_CUSTOM = 'type-custom';
const TYPE_DIVIDER = 'type-divider';
const TYPE_ICON = 'type-icon';
const STATUS_WARN = 'phui-list-item-warn';
const STATUS_FAIL = 'phui-list-item-fail';
private $name;
private $href;
private $type = self::TYPE_LINK;
private $isExternal;
private $key;
private $icon;
private $selected;
private $disabled;
private $renderNameAsTooltip;
private $statusColor;
private $order;
private $aural;
private $profileImage;
private $indented;
private $hideInApplicationMenu;
private $icons = array();
public function setHideInApplicationMenu($hide) {
$this->hideInApplicationMenu = $hide;
return $this;
}
public function getHideInApplicationMenu() {
return $this->hideInApplicationMenu;
}
public function setDropdownMenu(PhabricatorActionListView $actions) {
Javelin::initBehavior('phui-dropdown-menu');
$this->addSigil('phui-dropdown-menu');
- $this->setMetadata(
- array(
- 'items' => $actions,
- ));
+ $this->setMetadata($actions->getDropdownMenuMetadata());
return $this;
}
public function setAural($aural) {
$this->aural = $aural;
return $this;
}
public function getAural() {
return $this->aural;
}
public function setOrder($order) {
$this->order = $order;
return $this;
}
public function getOrder() {
return $this->order;
}
public function setRenderNameAsTooltip($render_name_as_tooltip) {
$this->renderNameAsTooltip = $render_name_as_tooltip;
return $this;
}
public function getRenderNameAsTooltip() {
return $this->renderNameAsTooltip;
}
public function setSelected($selected) {
$this->selected = $selected;
return $this;
}
public function getSelected() {
return $this->selected;
}
public function setIcon($icon) {
$this->icon = $icon;
return $this;
}
public function setProfileImage($image) {
$this->profileImage = $image;
return $this;
}
public function getIcon() {
return $this->icon;
}
public function setIndented($indented) {
$this->indented = $indented;
return $this;
}
public function getIndented() {
return $this->indented;
}
public function setKey($key) {
$this->key = (string)$key;
return $this;
}
public function getKey() {
return $this->key;
}
public function setType($type) {
$this->type = $type;
return $this;
}
public function getType() {
return $this->type;
}
public function setHref($href) {
$this->href = $href;
return $this;
}
public function getHref() {
return $this->href;
}
public function setName($name) {
$this->name = $name;
return $this;
}
public function getName() {
return $this->name;
}
public function setIsExternal($is_external) {
$this->isExternal = $is_external;
return $this;
}
public function getIsExternal() {
return $this->isExternal;
}
public function setStatusColor($color) {
$this->statusColor = $color;
return $this;
}
public function addIcon($icon) {
$this->icons[] = $icon;
return $this;
}
public function getIcons() {
return $this->icons;
}
protected function getTagName() {
return 'li';
}
protected function getTagAttributes() {
$classes = array();
$classes[] = 'phui-list-item-view';
$classes[] = 'phui-list-item-'.$this->type;
if ($this->icon) {
$classes[] = 'phui-list-item-has-icon';
}
if ($this->selected) {
$classes[] = 'phui-list-item-selected';
}
if ($this->disabled) {
$classes[] = 'phui-list-item-disabled';
}
if ($this->statusColor) {
$classes[] = $this->statusColor;
}
return array(
'class' => $classes,
);
}
public function setDisabled($disabled) {
$this->disabled = $disabled;
return $this;
}
public function getDisabled() {
return $this->disabled;
}
protected function getTagContent() {
$name = null;
$icon = null;
$meta = null;
$sigil = null;
if ($this->name) {
if ($this->getRenderNameAsTooltip()) {
Javelin::initBehavior('phabricator-tooltips');
$sigil = 'has-tooltip';
$meta = array(
'tip' => $this->name,
'align' => 'E',
);
} else {
$external = null;
if ($this->isExternal) {
$external = " \xE2\x86\x97";
}
// If this element has an aural representation, make any name visual
// only. This is primarily dealing with the links in the main menu like
// "Profile" and "Logout". If we don't hide the name, the mobile
// version of these elements will have two redundant names.
$classes = array();
$classes[] = 'phui-list-item-name';
if ($this->aural !== null) {
$classes[] = 'visual-only';
}
$name = phutil_tag(
'span',
array(
'class' => implode(' ', $classes),
),
array(
$this->name,
$external,
));
}
}
$aural = null;
if ($this->aural !== null) {
$aural = javelin_tag(
'span',
array(
'aural' => true,
),
$this->aural);
}
if ($this->icon) {
$icon_name = $this->icon;
if ($this->getDisabled()) {
$icon_name .= ' grey';
}
$icon = id(new PHUIIconView())
->addClass('phui-list-item-icon')
->setIcon($icon_name);
}
if ($this->profileImage) {
$icon = id(new PHUIIconView())
->setHeadSize(PHUIIconView::HEAD_SMALL)
->addClass('phui-list-item-icon')
->setImage($this->profileImage);
}
$classes = array();
if ($this->href) {
$classes[] = 'phui-list-item-href';
}
if ($this->indented) {
$classes[] = 'phui-list-item-indented';
}
$icons = $this->getIcons();
return javelin_tag(
$this->href ? 'a' : 'div',
array(
'href' => $this->href,
'class' => implode(' ', $classes),
'meta' => $meta,
'sigil' => $sigil,
),
array(
$aural,
$icon,
$icons,
$this->renderChildren(),
$name,
));
}
}

File Metadata

Mime Type
text/x-diff
Expires
Fri, Mar 14, 2:38 PM (1 d, 8 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
71956
Default Alt Text
(22 KB)

Event Timeline