/** * Generate a node ID which is guaranteed to be unique for the current page, * even across Ajax requests. You should use this method to generate IDs for * nodes which require a uniqueness guarantee. * * @return string A string appropriate for use as an 'id' attribute on a DOM * node. It is guaranteed to be unique for the current page, even * if the current request is a subsequent Ajax request. * * @group celerity */ function celerity_generate_unique_node_id() { static $uniq = 0; $response = CelerityAPI::getStaticResourceResponse(); $block = $response->getMetadataBlock(); return 'UQ' . $block . '_' . $uniq++; }
public static function getStaticResourceResponse() { if (empty(self::$response)) { self::$response = new CelerityStaticResourceResponse(); } return self::$response; }
public function buildResponseString() { $console = $this->getConsole(); if ($console) { // NOTE: We're stripping query parameters here both for readability and // to mitigate BREACH and similar attacks. The parameters are available // in the "Request" tab, so this should not impact usability. See T3684. $uri = $this->getRequest()->getRequestURI(); $uri = new PhutilURI($uri); $uri->setQueryParams(array()); Javelin::initBehavior('dark-console', array('uri' => (string) $uri, 'key' => $console->getKey($this->getRequest()), 'color' => $console->getColor(), 'quicksand' => $this->getRequest()->isQuicksand())); } // Flatten the response first, so we initialize any behaviors and metadata // we need to. $content = array('payload' => $this->content); $this->encodeJSONForHTTPResponse($content); $response = CelerityAPI::getStaticResourceResponse(); $request = $this->getRequest(); if ($request) { $viewer = $request->getViewer(); if ($viewer) { $postprocessor_key = $viewer->getUserSetting(PhabricatorAccessibilitySetting::SETTINGKEY); if (strlen($postprocessor_key)) { $response->setPostprocessorKey($postprocessor_key); } } } $object = $response->buildAjaxResponse($content['payload'], $this->error); $response_json = $this->encodeJSONForHTTPResponse($object); return $this->addJSONShield($response_json); }
/** * Get the versioned URI for a raw resource, like an image. * * @param string Path to the raw image. * @return string Versioned path to the image, if one is available. */ function celerity_get_resource_uri($resource, $source = 'phabricator') { $resource = ltrim($resource, '/'); $map = CelerityResourceMap::getNamedInstance($source); $response = CelerityAPI::getStaticResourceResponse(); return $response->getURI($map, $resource); }
public function buildResponseString() { $response = CelerityAPI::getStaticResourceResponse(); $object = $response->buildAjaxResponse($this->content, $this->error); $response_json = $this->encodeJSONForHTTPResponse($object); return $this->addJSONShield($response_json, $use_javelin_shield = true); }
public function buildResponseString() { $console = $this->getConsole(); if ($console) { Javelin::initBehavior('dark-console-ajax', array('console' => $console->render($this->getRequest()), 'uri' => (string) $this->getRequest()->getRequestURI())); } $response = CelerityAPI::getStaticResourceResponse(); $object = $response->buildAjaxResponse($this->content, $this->error); $response_json = $this->encodeJSONForHTTPResponse($object); return $this->addJSONShield($response_json, $use_javelin_shield = true); }
function javelin_tag($tag, array $attributes = array(), $content = null) { if (isset($attributes['sigil']) || isset($attributes['meta']) || isset($attributes['mustcapture'])) { foreach ($attributes as $k => $v) { switch ($k) { case 'sigil': if ($v !== null) { $attributes['data-sigil'] = $v; } unset($attributes[$k]); break; case 'meta': if ($v !== null) { $response = CelerityAPI::getStaticResourceResponse(); $id = $response->addMetadata($v); $attributes['data-meta'] = $id; } unset($attributes[$k]); break; case 'mustcapture': if ($v) { $attributes['data-mustcapture'] = '1'; } else { unset($attributes['data-mustcapture']); } unset($attributes[$k]); break; } } } if (isset($attributes['aural'])) { if ($attributes['aural']) { $class = idx($attributes, 'class', ''); $class = rtrim('aural-only ' . $class); $attributes['class'] = $class; } else { $class = idx($attributes, 'class', ''); $class = rtrim('visual-only ' . $class); $attributes['class'] = $class; $attributes['aria-hidden'] = 'true'; } unset($attributes['aural']); } return phutil_tag($tag, $attributes, $content); }
function javelin_render_tag($tag, array $attributes = array(), $content = null) { if (isset($attributes['sigil']) || isset($attributes['meta']) || isset($attributes['mustcapture'])) { foreach ($attributes as $k => $v) { switch ($k) { case 'sigil': $attributes['data-sigil'] = $v; unset($attributes[$k]); break; case 'meta': $response = CelerityAPI::getStaticResourceResponse(); $id = $response->addMetadata($v); $attributes['data-meta'] = $id; unset($attributes[$k]); break; case 'mustcapture': $attributes['data-mustcapture'] = '1'; unset($attributes[$k]); break; } } } return phutil_render_tag($tag, $attributes, $content); }
protected function getTail() { $response = CelerityAPI::getStaticResourceResponse(); return $response->renderResourcesOfType('js') . $response->renderHTMLFooter(); }
protected function getTail() { $request = $this->getRequest(); $user = $request->getUser(); $tail = array(parent::getTail()); $response = CelerityAPI::getStaticResourceResponse(); if (PhabricatorEnv::getEnvConfig('notification.enabled')) { if ($user && $user->isLoggedIn()) { $client_uri = PhabricatorEnv::getEnvConfig('notification.client-uri'); $client_uri = new PhutilURI($client_uri); if ($client_uri->getDomain() == 'localhost') { $this_host = $this->getRequest()->getHost(); $this_host = new PhutilURI('http://' . $this_host . '/'); $client_uri->setDomain($this_host->getDomain()); } if ($request->isHTTPS()) { $client_uri->setProtocol('wss'); } else { $client_uri->setProtocol('ws'); } Javelin::initBehavior('aphlict-listen', array('websocketURI' => (string) $client_uri) + $this->buildAphlictListenConfigData()); } } $tail[] = $response->renderHTMLFooter(); return $tail; }
public function buildResponseString() { $response = CelerityAPI::getStaticResourceResponse(); return $response->renderAjaxResponse($this->content, $this->error); }
public static function initBehavior($behavior, array $config = array(), $source_name = 'phabricator') { $response = CelerityAPI::getStaticResourceResponse(); $response->initBehavior($behavior, $config, $source_name); }
protected function getTail() { $request = $this->getRequest(); $user = $request->getUser(); $tail = array(parent::getTail()); $response = CelerityAPI::getStaticResourceResponse(); if (PhabricatorEnv::getEnvConfig('notification.enabled')) { if ($user && $user->isLoggedIn()) { $aphlict_object_id = celerity_generate_unique_node_id(); $aphlict_container_id = celerity_generate_unique_node_id(); $client_uri = PhabricatorEnv::getEnvConfig('notification.client-uri'); $client_uri = new PhutilURI($client_uri); if ($client_uri->getDomain() == 'localhost') { $this_host = $this->getRequest()->getHost(); $this_host = new PhutilURI('http://' . $this_host . '/'); $client_uri->setDomain($this_host->getDomain()); } $map = CelerityResourceMap::getNamedInstance('phabricator'); $swf_uri = $response->getURI($map, 'rsrc/swf/aphlict.swf', true); $enable_debug = PhabricatorEnv::getEnvConfig('notification.debug'); $subscriptions = $this->pageObjects; if ($user) { $subscriptions[] = $user->getPHID(); } Javelin::initBehavior('aphlict-listen', array('id' => $aphlict_object_id, 'containerID' => $aphlict_container_id, 'server' => $client_uri->getDomain(), 'port' => $client_uri->getPort(), 'debug' => $enable_debug, 'swfURI' => $swf_uri, 'pageObjects' => array_fill_keys($this->pageObjects, true), 'subscriptions' => $subscriptions)); $tail[] = phutil_tag('div', array('id' => $aphlict_container_id, 'style' => 'position: absolute; width: 0; height: 0; overflow: hidden;'), ''); } } $tail[] = $response->renderHTMLFooter(); return $tail; }
public final function render() { $filters = $this->queries->getParameter('filters', array()); $script_code = <<<EOT <script type="text/javascript" charset="utf-8"> \tvar wnd = window, \t el = document.documentElement, \t body = document.getElementsByTagName( 'body' )[ 0 ], \t width = wnd.innerWidth || el.clientWidth || body.clientWidth, \t height = wnd.innerHeight|| el.clientHeight || body.clientHeight; \theight -= 400; width -= 80; \tif ( width < 800 ) width = 800; \tif ( height < 600 ) height = 600; \tvar labelDistance = 0; \tvar vis = d3.select( "div.is4u_graph" ).append( "svg:svg" ).attr( "width", width ).attr( "height", height ); \tvar nodes = []; \tvar labelAnchors = []; \tvar labelAnchorLinks = []; \tvar links = []; EOT; $counter = 0; $tasks = array(); Javelin::initBehavior('phui-hovercards'); foreach ($this->tasks as $task) { $phid = $task->getPHID(); $tasks[$phid]["id"] = $counter++; $tasks[$phid]["is_source"] = 0; $tasks[$phid]["is_target"] = 0; } foreach ($this->tasks as $task) { $phid = $task->getPHID(); $target = $tasks[$phid]["id"]; foreach ($task->loadDependsOnTaskPHIDs() as $depend) { if (array_key_exists($depend, $tasks)) { $source = $tasks[$depend]["id"]; $tasks[$phid]["is_target"] = 1; $tasks[$depend]["is_source"] = 1; $script_code .= <<<EOT \t\tlinks.push( { source: {$source}, target: {$target} } ); EOT; } } } $response = CelerityAPI::getStaticResourceResponse(); $maxHours = 0; foreach ($this->tasks as $task) { $phid = $task->getPHID(); $title = trim($task->getTitle()); $title = str_replace("\n", ' ', $title); $owner = $this->handles[$task->getOwnerPHID()]; # add progress and estimated hours to hovered title $field_list = PhabricatorCustomField::getObjectFields($task, PhabricatorCustomField::ROLE_VIEW); $field_list->setViewer($this->viewer)->readFieldsFromStorage($task); $myFields = []; foreach ($field_list->getFields() as $key => $field) { $field->setViewer($this->viewer); $fname = $field->getFieldKey(); $fproxy = $field->getProxy(); if ($fproxy != null) { $myFields[$fname] = $fproxy->getFieldValue(); } } if (!array_key_exists('std:maniphest:is4u:estimated-hours', $myFields) || !isset($myFields['std:maniphest:is4u:estimated-hours'])) { $myFields['std:maniphest:is4u:estimated-hours'] = 1; } if (!array_key_exists('std:maniphest:is4u:progress', $myFields) || !isset($myFields['std:maniphest:is4u:progress'])) { $myFields['std:maniphest:is4u:progress'] = 0; } if (array_key_exists('std:maniphest:is4u:estimated-hours', $myFields) && array_key_exists('std:maniphest:is4u:progress', $myFields)) { $title .= sprintf(" (%s, %d hours, %d %% progress)", $owner->getName(), $myFields['std:maniphest:is4u:estimated-hours'], $myFields['std:maniphest:is4u:progress']); } else { $title .= sprintf(" (%s)", $owner->getName()); } $title = phutil_escape_html($title); $progress = 0; if (array_key_exists('std:maniphest:is4u:progress', $myFields)) { $progress = $myFields['std:maniphest:is4u:progress']; if ($progress < 0) { $progress = 0; } if ($progress > 100) { $progress = 100; } } $estimatedHours = 0; if (array_key_exists('std:maniphest:is4u:estimated-hours', $myFields)) { $estimatedHours = $myFields['std:maniphest:is4u:estimated-hours']; if ($estimatedHours < 1) { $estimatedHours = 1; } if ($estimatedHours > $maxHours) { $maxHours = $estimatedHours; } } $myTask = $task->getOwnerPHID() == $this->viewer->getPHID(); $blocker = $tasks[$phid]["is_source"] && !$tasks[$phid]["is_target"]; $myBlocker = $myTask && $blocker; $color = $myBlocker ? '#F00' : ($blocker ? '#F3F' : ($myTask ? '#00F' : '#777')); $id = $task->getId(); $label = "T{$id}"; $label = phutil_escape_html($label); $meta_id = $response->addMetadata(array('hoverPHID' => $phid)); $show = 1; $standalone = !$tasks[$phid]["is_source"] && !$tasks[$phid]["is_target"]; if ($standalone && $myTask && in_array('my_standalone', $filters)) { $show = 0; } if ($standalone && !$myTask && in_array('others_standalone', $filters)) { $show = 0; } $script_code .= <<<EOT \tvar node = { label: "{$label}", title: "{$title}", color: "{$color}", meta: "{$meta_id}", show: "{$show}", my: "{$myTask}", adjacentNodes: [], adjacentLinks: [], progress: {$progress}, estimatedHours: {$estimatedHours} }; \tnodes.push( node ); EOT; } $script_code .= <<<EOT \tfor ( var i = 0; i < links.length; i++ ) { \t\tlinks[ i ].source = nodes[ links[ i ].source ]; links[ i ].target = nodes[ links[ i ].target ]; \t\tlinks[ i ].source.adjacentNodes.push( links[ i ].target ); links[ i ].source.adjacentLinks.push( links[ i ] ); \t\tlinks[ i ].target.adjacentNodes.push( links[ i ].source ); links[ i ].target.adjacentLinks.push( links[ i ] ); \t} \tif ( ! Array.prototype.indexOf ) \t\tArray.prototype.indexOf = function( elt /*, from*/ ) { \t\t\tvar len = this.length >>> 0; \t\t\tvar from = Number(arguments[1]) || 0; \t\t\tfrom = (from < 0) ? Math.ceil(from) : Math.floor(from); \t\t\tif (from < 0) from += len; \t\t\tfor (; from < len; from++) if (from in this && this[from] === elt) return from; \t\t\treturn -1; \t\t}; \tfunction bfs ( v ) { \t\tvar queue = []; \t\tvar result = []; \t\tqueue.push( v ); \t\tv.bfsMark = true; \t\twhile ( queue.length > 0 ) { \t\t\tvar t = queue.shift(); \t\t\tif ( t != v ) result.push( t ); \t\t\tfor ( var i = 0; i < t.adjacentNodes.length; i++ ) \t\t\t\tif ( ! t.adjacentNodes[ i ].bfsMark ) { \t\t\t\t\tt.adjacentNodes[ i ].bfsMark = true; \t\t\t\t\tqueue.push( t.adjacentNodes[ i ] ); \t\t\t\t} \t\t} \t\tfor ( var i = 0; i < nodes.length; i++ ) nodes[ i ].bfsMark = false; \t\treturn result; \t} EOT; if (in_array('others_clusters', $filters)) { $script_code .= <<<EOT \tfor (var i = 0; i < nodes.length; i++ ) \t\tif ( nodes[ i ].my == "1" ) { \t\t\tnodes[ i ].keep = true; \t\t\tvar connected = bfs( nodes[ i ] ); \t\t\tfor ( var j = 0; j < connected.length; j++ ) \t\t\t\tconnected[ j ].keep = true; \t\t} \tfor ( var i = 0; i < nodes.length; i++ ) if ( ! nodes[ i ].keep ) nodes[ i ].show = "0"; EOT; } if (in_array('redundant_links', $filters)) { $script_code .= <<<EOT \tfor ( var i = 0; i < links.length; i++ ) links[ i ].redundant = false; \tfor ( var i = 0; i < nodes.length; i++ ) \t\tfor ( var j = 0; j < nodes[ i ].adjacentNodes.length; j++ ) { \t\t\tvar connected = bfs( nodes[ i ].adjacentNodes[ j ] ); \t\t\tif ( connected.length > 0 ) \t\t\t\tfor ( var k = 0; k < nodes[ i ].adjacentLinks.length; k++ ) \t\t\t\t\tif ( connected.indexOf( nodes[ i ].adjacentLinks[ k ].target ) >= 0 ) \t\t\t\t\t\tnodes[ i ].adjacentLinks[ k ].redundant = true; \t\t} \tfor ( var i = links.length-1; i >= 0; i-- ) if ( links[ i ].redundant ) links.splice( i, 1 ); EOT; } $script_code .= <<<EOT \tlinks = links.filter( function ( d ) { return d.source.show == "1" && d.target.show == "1"; } ) \tfor ( var i = 0; i < nodes.length; i++ ) { \t\tlabelAnchors.push( { node: nodes[ i ] } ); \t\tlabelAnchors.push( { node: nodes[ i ] } ); \t} \tfor ( var i = 0; i < nodes.length; i++ ) { labelAnchorLinks.push( { source: i * 2, target: i * 2 + 1 } ); } \tvar force = d3.layout.force() \t\t.size( [ width, height ] ) \t\t.nodes( nodes ) \t\t.links( links ) \t\t.gravity( 1 ) \t\t.linkDistance( 20 ) \t\t.charge( -3000 ) \t\t.linkStrength( 2 ) \tforce.start(); \tvar force2 = d3.layout.force() \t\t.nodes( labelAnchors ) \t\t.links( labelAnchorLinks ) \t\t.gravity( 0 ) \t\t.linkDistance( 0 ) \t\t.linkStrength( 8 ) \t\t.charge( -100 ) \t\t.size( [ width, height ] ); \tforce2.start(); \tvis.append( "svg:defs" ) \t\t.append( "marker" ) \t\t\t.attr( "id", "triangle" ) \t\t\t.attr( "viewbox", "0 0 10 10" ) \t\t\t.attr( "markerWidth", 10 ) \t\t\t.attr( "markerHeight", 10 ) \t\t\t.attr( "refX", 15 ) \t\t\t.attr( "refY", 5 ) \t\t\t.attr( "orient", "auto" ) \t\t\t.attr( "markerUnits", "strokeWidth" ) \t\t\t.append( "polyline" ) \t\t\t\t.attr( "points", "0,0 10,5 0,10 1,5" ) \t\t\t\t.style( "fill", "#999" ); \tvar link = vis.selectAll("line.link") \t\t.data(links) \t\t.enter().append("svg:line") \t\t\t.attr("class", "link") \t\t\t.style("stroke", "#999") \t\t\t.attr( "marker-end", "url(#triangle)" ); \tif ( links.length == 0 ) { \t\td3.selectAll("line.link").remove(); \t} \tforce.nodes( force.nodes().filter( function ( d ) { return d.show == "1"; } ) ); \tforce2.nodes( force2.nodes().filter( function ( d ) { return d.node.show == "1"; } ) ); \tvar node = vis.selectAll("g.node") \t\t.data(force.nodes()) \t\t.enter().append("svg:g") \t\t\t.attr("class", "node"); \tnode.append("svg:circle") \t\t.attr("r", 5) \t\t.style("fill", function (d) { return d.color; } ) \t\t.style("stroke", "#FFF") \t\t.style("stroke-width", 3) \t\t.append( "title" ) \t\t\t.text( function (d, i) { return d.label + " " + d.title; }); \tnode.call(force.drag); \tvar anchorLink = vis.selectAll("line.anchorLink").data(labelAnchorLinks); \tvar anchorNode = vis.selectAll("g.anchorNode") \t\t.data(force2.nodes()) \t\t.enter().append("svg:g") \t\t\t.attr("class", "anchorNode"); \tanchorNode.append("svg:circle") \t\t.attr("r", 0) \t\t.style("fill", "#FFF"); \tanchorNode.append("svg:text") \t\t.attr( 'data-sigil', 'hovercard' ) \t\t.attr( 'data-meta', function ( d ) { if ( d ) return d.node.meta; } ) \t\t.text( function(d, i) { return i % 2 == 0 ? "" : d.node.label }) \t\t.style( "fill", function ( d ) { return d.node.color; } ) \t\t.style( "font-family", "Arial" ) \t\t.style( "font-size", 12 ) \t\t.style( "cursor", "pointer" ) \t\t.on( 'click', function( d,i ) { if ( d ) { window.open( "/" + d.node.label, "_blank" ); d3.event.stopPropagation(); } } ) \t\t.append( 'svg:title' ) \t\t\t.text( function (d, i) { return i % 2 == 0 ? "" : d.node.label + " " + d.node.title }); \tvar updateLink = function() { \t\tthis \t\t\t.attr("x1", function(d) { return d.source.x; }) \t\t\t.attr("y1", function(d) { return d.source.y; }) \t\t\t.attr("x2", function(d) { return d.target.x; }) \t\t\t.attr("y2", function(d) { return d.target.y; }); \t} \tvar updateNode = function() { this.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); } \tforce.on("tick", function() { \t\tforce2.start(); \t\tnode.call(updateNode); \t\tanchorNode.each(function(d, i) { \t\t\tif(i % 2 == 0) { \t\t\t\td.x = d.node.x; \t\t\t\td.y = d.node.y; \t\t\t} else { \t\t\t\tvar b = this.childNodes[1].getBBox(); \t\t\t\tvar diffX = d.x - d.node.x; \t\t\t\tvar diffY = d.y - d.node.y; \t\t\t\tvar dist = Math.sqrt(diffX * diffX + diffY * diffY); \t\t\t\tvar shiftX = b.width * (diffX - dist) / (dist * 2); \t\t\t\tshiftX = Math.max(-b.width, Math.min(0, shiftX)); \t\t\t\tvar shiftY = 5; \t\t\t\tthis.childNodes[1].setAttribute("transform", "translate(" + shiftX + "," + shiftY + ")"); \t\t\t} \t\t}); \t\tanchorNode.call(updateNode); \t\tlink.call(updateLink); \t\tanchorLink.call(updateLink); \t}); </script> EOT; $box_content = new PhutilSafeHTML($script_code); $box = id(new PHUIBoxView())->appendChild(phutil_tag('div', array("class" => "is4u_graph"), ''))->appendChild(phutil_tag('script', array('src' => $this->uri)))->appendChild($box_content)->appendChild(phutil_tag('div', array(), pht('Links indicate dependency "this task has to be done before that". Blue one tasks are yours. Red ones represent your true blockers while magenta other blocking tasks.')))->addPadding(PHUI::PADDING_LARGE); $header = id(new PHUIHeaderView())->setHeader($this->header); $filter_header = id(new PHUIHeaderView())->setHeader(pht('Filters')); $filter_defs = array('my_standalone' => pht('my standalone tasks'), 'others_standalone' => pht('others standalone tasks'), 'others_clusters' => pht('clusters without my tasks'), 'redundant_links' => pht('redundant dependencies')); $cb = id(new AphrontFormCheckboxControl())->setLabel('Hide'); foreach ($filter_defs as $k => $v) { $cb->addCheckbox('filters[]', $k, pht($v), in_array($k, $filters)); } $filter = id(new AphrontFormView())->setUser($this->viewer)->appendChild($cb)->appendChild(id(new AphrontFormSubmitControl())->setValue(pht('Filter'))); $filter_box = id(new PHUIBoxView())->appendChild($filter_header)->appendChild($filter)->setBorder(true)->addMargin(PHUI::MARGIN_LARGE_TOP)->addMargin(PHUI::MARGIN_LARGE_LEFT)->addMargin(PHUI::MARGIN_LARGE_RIGHT)->addClass('phui-object-box'); $fullbox = id(new PHUIBoxView())->appendChild($header)->appendChild($box)->setBorder(true)->addMargin(PHUI::MARGIN_LARGE_TOP)->addMargin(PHUI::MARGIN_LARGE_LEFT)->addMargin(PHUI::MARGIN_LARGE_RIGHT)->addClass('phui-object-box'); $rendered = id(new PHUIBoxView())->appendChild($filter_box)->appendChild($fullbox); return $rendered; }
protected function getTail() { $request = $this->getRequest(); $user = $request->getUser(); $container = null; if (PhabricatorEnv::getEnvConfig('notification.enabled') && $user->isLoggedIn()) { $aphlict_object_id = celerity_generate_unique_node_id(); $aphlict_container_id = celerity_generate_unique_node_id(); $client_uri = PhabricatorEnv::getEnvConfig('notification.client-uri'); $client_uri = new PhutilURI($client_uri); if ($client_uri->getDomain() == 'localhost') { $this_host = $this->getRequest()->getHost(); $this_host = new PhutilURI('http://' . $this_host . '/'); $client_uri->setDomain($this_host->getDomain()); } $enable_debug = PhabricatorEnv::getEnvConfig('notification.debug'); Javelin::initBehavior('aphlict-listen', array('id' => $aphlict_object_id, 'containerID' => $aphlict_container_id, 'server' => $client_uri->getDomain(), 'port' => $client_uri->getPort(), 'debug' => $enable_debug, 'pageObjects' => array_fill_keys($this->pageObjects, true))); $container = phutil_render_tag('div', array('id' => $aphlict_container_id, 'style' => 'position: absolute; width: 0; height: 0;'), ''); } $response = CelerityAPI::getStaticResourceResponse(); return $response->renderResourcesOfType('js') . $container . $response->renderHTMLFooter(); }
public function requireResource($symbol) { $response = CelerityAPI::getStaticResourceResponse(); $response->requireResource($symbol, $this->getDefaultResourceSource()); return $this; }
protected function getTail() { $request = $this->getRequest(); $user = $request->getUser(); $tail = array(parent::getTail()); $response = CelerityAPI::getStaticResourceResponse(); if ($request->isHTTPS()) { $with_protocol = 'https'; } else { $with_protocol = 'http'; } $servers = PhabricatorNotificationServerRef::getEnabledClientServers($with_protocol); if ($servers) { if ($user && $user->isLoggedIn()) { // TODO: We could tell the browser about all the servers and let it // do random reconnects to improve reliability. shuffle($servers); $server = head($servers); $client_uri = $server->getWebsocketURI(); Javelin::initBehavior('aphlict-listen', array('websocketURI' => (string) $client_uri) + $this->buildAphlictListenConfigData()); } } $tail[] = $response->renderHTMLFooter(); return $tail; }
public static function initBehavior($behavior, array $config = array()) { $response = CelerityAPI::getStaticResourceResponse(); $response->initBehavior($behavior, $config); }