コード例 #1
0
ファイル: Q_responseExtras.php プロジェクト: EGreg/Overlay
function Overlay_before_Q_responseExtras()
{
    $app = Q_Config::expect('Q', 'app');
    Q_Response::addStylesheet('plugins/Q/css/Q.css');
    Q_Response::addStylesheet('css/Overlay.css', '@end');
    Q_Response::addStylesheet('http://fonts.googleapis.com/css?family=Open+Sans:400italic,400,300,700');
    if (Q_Config::get('Q', 'firebug', false)) {
        Q_Response::addScript("https://getfirebug.com/firebug-lite-debug.js");
    }
    Q_Response::addScript('js/Overlay.js');
    Q_Response::setMeta("title", "Customize My Pic!");
    Q_Response::setMeta("description", "Make a statement on Facebook by customizing your profile picture, even from your smartphone.");
    Q_Response::setMeta("image", Q_Html::themedUrl('img/icon/icon.png'));
    if (Q_Request::isIE()) {
        header("X-UA-Compatible", "IE=edge");
    }
    header('Vary: User-Agent');
    // running an event for loading action-specific extras (if there are any)
    $uri = Q_Dispatcher::uri();
    $module = $uri->module;
    $action = $uri->action;
    $event = "{$module}/{$action}/response/responseExtras";
    if (Q::canHandle($event)) {
        Q::event($event);
    }
}
コード例 #2
0
ファイル: post.php プロジェクト: dmitriz/Platform
function Q_post($params)
{
    $uri = Q_Dispatcher::uri();
    $module = $uri->module;
    $action = $uri->action;
    if (!Q::canHandle("{$module}/{$action}/post")) {
        throw new Q_Exception_MethodNotSupported(array('method' => 'POST'));
    }
    if (isset($_SERVER['CONTENT_LENGTH'])) {
        $contentLength = (int) $_SERVER['CONTENT_LENGTH'];
        foreach (array('upload_max_filesize', 'post_max_size') as $name) {
            $value = ini_get($name);
            switch (substr($value, -1)) {
                case 'K':
                    $value *= 1024;
                    break;
                case 'M':
                    $value *= 1024 * 1024;
                    break;
                case 'B':
                    $value *= 1024 * 1024 * 1024;
                    break;
            }
            if ($contentLength > $value) {
                throw new Q_Exception_ContentLength(array('contentLength' => $contentLength, 'exceeds' => $name));
            }
        }
    }
    return Q::event("{$module}/{$action}/post", $params);
}
コード例 #3
0
ファイル: validate.php プロジェクト: dmitriz/Platform
function Streams_publisher_validate($params)
{
    // Protect against CSRF attacks:
    Q_Valid::nonce(true);
    $type = Streams::requestedType();
    if ($type && Q::canHandle("Streams/validate/{$type}")) {
        return Q::event("Streams/validate/{$type}", $params);
    }
}
コード例 #4
0
ファイル: validate.php プロジェクト: dmitriz/Platform
function Users_importContacts_validate()
{
    Q_Valid::nonce(true);
    if (empty($_GET['provider'])) {
        throw new Q_Exception('No provider specified');
    }
    if (!Q::canHandle('Users/importContacts/providers/' . $_GET['provider'])) {
        throw new Q_Exception('Unsupported provider specified: ' . $_GET['provider']);
    }
}
コード例 #5
0
ファイル: validate.php プロジェクト: dmitriz/Platform
function Q_validate($params)
{
    $uri = Q_Dispatcher::uri();
    $module = $uri->module;
    $action = $uri->action;
    if (!Q::canHandle("{$module}/{$action}/validate")) {
        return null;
    }
    return Q::event("{$module}/{$action}/validate", $params);
}
コード例 #6
0
ファイル: put.php プロジェクト: dmitriz/Platform
function Q_put($params)
{
    $uri = Q_Dispatcher::uri();
    $module = $uri->module;
    $action = $uri->action;
    if (!Q::canHandle("{$module}/{$action}/put")) {
        throw new Q_Exception_MethodNotSupported(array('method' => 'PUT'));
    }
    return Q::event("{$module}/{$action}/put", $params);
}
コード例 #7
0
ファイル: delete.php プロジェクト: AndreyTepaykin/Platform
function Q_delete($params)
{
    $uri = Q_Dispatcher::uri();
    $module = $uri->module;
    $action = $uri->action;
    if (!Q::canHandle("{$module}/{$action}/delete")) {
        throw new Q_Exception_MethodNotSupported(array('method' => 'DELETE'));
    }
    Q_Request::requireValidNonce();
    return Q::event("{$module}/{$action}/delete", $params);
}
コード例 #8
0
ファイル: tool.php プロジェクト: dmitriz/Platform
/**
 * This tool generates an interface used for publishing messages to streams
 * It basically renders the Streams/player/$type tool, where $type is the stream's type.
 *
 * @param array $options
 *  An associative array of parameters, containing:
 *  "publisherId" => required. The id of the publisher of the stream to which to post the message.
 *  "streamName" => required. The name of the stream to which to post the message.
 */
function Streams_player_tool($options)
{
    extract($options);
    if (empty($stream)) {
        throw new Q_Exception("Missing stream object");
    }
    if (!Q::canHandle('Streams/player/' . $stream->type . '/tool')) {
        throw new Q_Exception("No player tool has been implemented for streams of type {$stream->type}.");
    }
    return Q::tool('Streams/player/' . $stream->type, $options);
}
コード例 #9
0
ファイル: validate.php プロジェクト: dmitriz/Platform
function Streams_stream_validate($params)
{
    // Protect against CSRF attacks:
    if (Q_Request::method() !== 'GET') {
        Q_Valid::nonce(true);
    }
    $type = Streams::requestedType();
    if ($type && Q::canHandle("Streams/validate/{$type}")) {
        return Q::event("Streams/validate/{$type}", $params);
    }
}
コード例 #10
0
ファイル: tool.php プロジェクト: AndreyTepaykin/Platform
function Streams_player_tool($options)
{
    extract($options);
    if (!isset($stream)) {
        throw new Q_Exception_MissingObject(array('name' => 'stream'));
    }
    if (!$stream->testReadLevel('content')) {
        $streamName_html = Q_Html::text($stream->name);
        return "<a href='#{$streamName_html}'>hidden</a>";
    }
    $options['streamName'] = $stream->name;
    $parts = explode('/', $stream->type);
    switch ($parts[0]) {
        case 'Streams/text/small':
        case 'Streams/text/medium':
        case 'Streams/text':
            return $stream->content;
        case 'Streams/date':
            // TODO: localize
            if (isset($parts[1]) and $parts[1] === 'birthday') {
                return date('M j', strtotime($stream->content));
            }
            return date('M j, Y', strtotime($stream->content));
        case 'Streams/number':
            if (isset($parts[1]) and $parts[1] === 'age') {
                if (!empty($streams['Streams/user/birthday']->content)) {
                    return Db::ageFromDateTime($streams['Streams/user/birthday']->content);
                }
                return null;
            }
            return $strem->content;
        case 'Streams/category':
            // TODO: implement
        // TODO: implement
        case 'Streams/chat':
            // TODO: implement
        // TODO: implement
        case 'Streams/community':
            // TODO: implement
        // TODO: implement
        default:
            $event = $stream->type . "/tool";
            if (Q::canHandle($event)) {
                return Q::tool($stream->type, $options);
            }
            return Q_Html::tag('div', array('class' => 'Streams_player_stream_content'), Q_Html::text($stream->content));
    }
}
コード例 #11
0
ファイル: content.php プロジェクト: dmitriz/Platform
function Q_response_content()
{
    $app = Q_Config::expect('Q', 'app');
    $url = Q_Request::url();
    $module = Q_Dispatcher::uri()->module;
    if (empty($module)) {
        return Q::event("{$app}/notFound/response/content");
    }
    $action = Q_Dispatcher::uri()->action;
    $event = "{$module}/{$action}/response/content";
    if (!Q::canHandle($event)) {
        return Q::event("{$app}/notFound/response/content");
    }
    // Go ahead and fire the event, returning the result.
    return Q::event($event);
}
コード例 #12
0
ファイル: content.php プロジェクト: AndreyTepaykin/Platform
function Q_response_content()
{
    $app = Q_Config::expect('Q', 'app');
    $url = Q_Request::url();
    $module = Q_Dispatcher::uri()->module;
    if (empty($module)) {
        return Q::event("{$app}/notFound/response/content");
    }
    $action = Q_Dispatcher::uri()->action;
    $event = "{$module}/{$action}/response/content";
    if (!Q::canHandle($event)) {
        return Q::event("{$app}/notFound/response/content");
    }
    Q_Response::setMeta('format-detection', 'telephone=no,date=no,address=no,email=no,url=no');
    // Go ahead and fire the event, returning the result.
    return Q::event($event);
}
コード例 #13
0
function Trump_before_Q_responseExtras()
{
    $app = Q_Config::expect('Q', 'app');
    Q_Response::addStylesheet('plugins/Q/css/Q.css');
    Q_Response::addStylesheet('css/html.css', '@end');
    if (Q_Config::get('Q', 'firebug', false)) {
        Q_Response::addScript("https://getfirebug.com/firebug-lite-debug.js");
    }
    Q_Response::addScript('js/Trump.js');
    if (Q_Request::isIE()) {
        header("X-UA-Compatible: IE=edge");
    }
    header('Vary: User-Agent');
    // running an event for loading action-specific extras (if there are any)
    $uri = Q_Dispatcher::uri();
    $module = $uri->module;
    $action = $uri->action;
    $event = "{$module}/{$action}/response/responseExtras";
    if (Q::canHandle($event)) {
        Q::event($event);
    }
}
コード例 #14
0
ファイル: default.php プロジェクト: dmitriz/Platform
function Q_response_default($params)
{
    if (!isset($params['slotName'])) {
        throw new Q_Exception_RequiredField(array('field' => '$slotName'));
    }
    $slotName = $params['slotName'];
    $uri = Q_Dispatcher::uri();
    $module = $uri->module;
    $action = $uri->action;
    if (!$module or !$action) {
        return "{$module}/{$action} is not a valid URI";
    }
    $event = "{$module}/{$action}/response/{$slotName}";
    $function_name = $module . '_' . $action . '_response_' . $slotName;
    if (function_exists($function_name)) {
        $result = Q::event($event);
        $result = isset($result) ? $result : "Don't return null from {$function_name}";
    }
    if (Q::canHandle($event)) {
        return Q::event($event);
    }
    throw new Q_Exception_MissingSlot(compact('event'));
}
コード例 #15
0
ファイル: response.php プロジェクト: atirjavid/Platform
/**
 * Default Q/response handler.
 * 1. Gets some slots, depending on what was requested.
 * 2. Renders them in a layout
 *    The layout expects "title", "dashboard" and "contents" slots to be filled.
 */
function Q_response($params)
{
    extract($params);
    /**
     * @var Exception $exception
     * @var array $errors
     */
    if (empty($errors)) {
        $errors = Q_Response::getErrors();
    }
    if (!empty($_GET['Q_ct'])) {
        Q_Response::setCookie('Q_ct', $_GET['Q_ct']);
    }
    // If output is set, use that
    $output = Q_Response::output();
    if (isset($output)) {
        if ($output === true) {
            return;
        }
        if (is_string($output)) {
            echo $output;
        }
        return;
    }
    // Redirect to success page, if requested.
    $isAjax = Q_Request::isAjax();
    if (empty($errors) and empty($exception)) {
        if (!$isAjax and null !== Q_Request::special('onSuccess', null)) {
            $onSuccess = Q_Request::special('onSuccess', null);
            if (Q_Config::get('Q', 'response', 'onSuccessShowFrom', true)) {
                $onSuccess = Q_Uri::url($onSuccess . '?Q.fromSuccess=' . Q_Dispatcher::uri());
            }
            Q_Response::redirect($onSuccess);
            return;
        }
    }
    // Get the requested module
    $uri = Q_Dispatcher::uri();
    if (!isset($module)) {
        $module = $uri->module;
        if (!isset($module)) {
            $module = 'Q';
            Q_Dispatcher::uri()->module = 'Q';
        }
    }
    if (!$isAjax || Q_Request::isLoadExtras()) {
        Q::event('Q/responseExtras', array(), 'before');
    }
    // Get the main module (the app)
    $app = Q_Config::expect('Q', 'app');
    $action = $uri->action;
    if (Q::canHandle("{$module}/{$action}/response")) {
        if (false === Q::event("{$module}/{$action}/response") and !$isAjax) {
            return;
        }
    }
    $slotNames = Q_Request::slotNames(true);
    $idPrefixes = array();
    if ($temp = Q_Request::special('idPrefixes', null)) {
        foreach (explode(',', $temp) as $i => $prefix) {
            if (!isset($slotNames[$i])) {
                throw new Q_Exception("More id prefixes than slot names", "Q.idPrefixes");
            }
            $idPrefixes[$slotNames[$i]] = $prefix;
        }
    }
    // What to do if this is an AJAX request
    if ($isAjax) {
        $to_encode = array();
        if (Q_Response::$redirected) {
            // We already called Q_Response::redirect
            $to_encode['redirect']['url'] = Q_Uri::url(Q_Response::$redirected);
            try {
                $to_encode['redirect']['uri'] = Q_Uri::from(Q_Response::$redirected)->toArray();
            } catch (Exception $e) {
                // couldn't get internal URI
            }
        } else {
            if (is_array($slotNames)) {
                foreach ($slotNames as $slotName) {
                    Q_Response::fillSlot($slotName, 'default', Q::ifset($idPrefixes, $slotName, null));
                }
                // Go through the slots again, because other handlers may have overwritten
                // their contents using Q_Response::setSlot()
                foreach ($slotNames as $sn) {
                    Q_Response::fillSlot($sn, 'default', Q::ifset($idPrefixes, $slotName, null));
                }
                if (Q_Response::$redirected) {
                    // While rendering the slots we called Q_Redirect
                    $to_encode['redirect']['url'] = Q_Uri::url(Q_Response::$redirected);
                    try {
                        $to_encode['redirect']['uri'] = Q_Uri::from(Q_Response::$redirected)->toArray();
                    } catch (Exception $e) {
                        // couldn't get internal URI
                    }
                } else {
                    if (Q_Request::isLoadExtras()) {
                        $to_encode['slots'] = Q_Response::slots(true);
                        // add stylesheets, stylesinline, scripts, scriptlines, scriptdata, templates
                        foreach (array_merge(array(''), $slotNames) as $slotName) {
                            $temp = Q_Response::stylesheetsArray($slotName);
                            if ($temp) {
                                $to_encode['stylesheets'][$slotName] = $temp;
                            }
                            $temp = Q_Response::stylesInline($slotName);
                            if ($temp) {
                                $to_encode['stylesInline'][$slotName] = $temp;
                            }
                            $temp = Q_Response::scriptsArray($slotName);
                            if ($temp) {
                                $to_encode['scripts'][$slotName] = $temp;
                            }
                            $temp = Q_Response::scriptLines($slotName, true, "\n", false);
                            if ($temp) {
                                $to_encode['scriptLines'][$slotName] = $temp;
                            }
                            $temp = Q_Response::scriptData($slotName);
                            if ($temp) {
                                $to_encode['scriptData'][$slotName] = $temp;
                            }
                            $temp = Q_Response::templateData($slotName);
                            if ($temp) {
                                $to_encode['templates'][$slotName] = $temp;
                            }
                        }
                    } else {
                        $to_encode['slots'] = Q_Response::slots(true);
                        // add stylesinline, scriptlines, scriptdata, templates
                        foreach (array_merge(array(''), $slotNames) as $slotName) {
                            $temp = Q_Response::stylesInline($slotName);
                            if ($temp) {
                                $to_encode['stylesInline'][$slotName] = $temp;
                            }
                            $temp = Q_Response::scriptData($slotName);
                            if ($temp) {
                                $to_encode['scriptData'][$slotName] = $temp;
                            }
                            $temp = Q_Response::scriptLines($slotName, true, "\n", false);
                            if ($temp) {
                                $to_encode['scriptLines'][$slotName] = $temp;
                            }
                        }
                    }
                }
            }
        }
        $to_encode['timestamp'] = microtime(true);
        $echo = Q_Request::contentToEcho();
        if (isset($echo)) {
            $to_encode['echo'] = $echo;
        }
        $json = Q::json_encode(Q::cutoff($to_encode));
        $callback = Q_Request::callback();
        switch (strtolower($isAjax)) {
            case 'iframe':
                if (!Q_Response::$batch) {
                    header("Content-type: text/html");
                }
                echo <<<EOT
<!doctype html><html lang=en>
<head><meta charset=utf-8><title>Q Result</title></head>
<body>
<script type="text/javascript">
window.result = function () { return {$json} };
</script>
</body>
</html>
EOT;
                break;
            case 'json':
            default:
                if (!Q_Response::$batch) {
                    header("Content-type: " . ($callback ? "application/javascript" : "application/json"));
                }
                echo $callback ? "{$callback}({$json})" : $json;
        }
        return;
    }
    // If this is a request for a regular webpage,
    // fill the usual slots and render a layout.
    if (Q_Response::$redirected) {
        return;
        // If already set a redirect header, simply return -- no reason to output all this HTML
    }
    static $added_Q_init = false;
    if (!$added_Q_init) {
        Q_Response::addScriptLine("\n// Now, initialize Q\nQ.init();\n", null, 'Q');
        $added_Q_init = true;
    }
    // Get all the usual slots for a webpage
    $slots = array();
    foreach ($slotNames as $sn) {
        Q_Response::fillSlot($sn, 'default', Q::ifset($idPrefixes, $sn, null));
    }
    // Go through the slots again, because other handlers may have overwritten
    // their contents using Q_Response::setSlot()
    foreach ($slotNames as $sn) {
        Q_Response::fillSlot($sn, 'default', Q::ifset($idPrefixes, $sn, null));
    }
    $output = Q_Response::output();
    if (isset($output)) {
        if ($output === true) {
            return;
        }
        if (is_string($output)) {
            echo $output;
        }
        return;
    }
    if (!$isAjax or Q_Request::isLoadExtras()) {
        Q::event('Q/responseExtras', array(), 'after');
    }
    $slots = Q_Response::slots(false);
    // Render a full HTML layout
    $layout_view = Q_Response::layoutView();
    echo Q::view($layout_view, $slots);
}
コード例 #16
0
ファイル: errors.php プロジェクト: AndreyTepaykin/Platform
/**
 * The default implementation.
 */
function Q_errors($params)
{
    extract($params);
    /**
     * @var Exception $exception
     * @var boolean $startedResponse
     */
    if (!empty($exception)) {
        Q_Response::addError($exception);
    }
    $errors = Q_Response::getErrors();
    $errors_array = Q_Exception::toArray($errors);
    // Simply return the errors, if this was an AJAX request
    if ($is_ajax = Q_Request::isAjax()) {
        try {
            $errors_json = @Q::json_encode($errors_array);
        } catch (Exception $e) {
            $errors_array = array_slice($errors_array, 0, 1);
            unset($errors_array[0]['trace']);
            $errors_json = @Q::json_encode($errors_array);
        }
        $json = "{\"errors\": {$errors_json}}";
        $callback = Q_Request::callback();
        switch (strtolower($is_ajax)) {
            case 'iframe':
                if (!Q_Response::$batch) {
                    header("Content-type: text/html");
                }
                echo <<<EOT
<!doctype html><html lang=en>
<head><meta charset=utf-8><title>Q Result</title></head>
<body>
<script type="text/javascript">
window.result = function () { return {$json} };
</script>
</body>
</html>
EOT;
                break;
            case 'json':
            default:
                header("Content-type: " . ($callback ? "application/javascript" : "application/json"));
                echo $callback ? "{$callback}({$json})" : $json;
        }
        return;
    }
    // Forward internally, if it was requested
    if ($onErrors = Q_Request::special('onErrors', null)) {
        $uri1 = Q_Dispatcher::uri();
        $uri2 = Q_Uri::from($onErrors);
        $url2 = $uri2->toUrl();
        if (!isset($uri2)) {
            throw new Q_Exception_WrongValue(array('field' => 'onErrors', 'range' => 'an internal URI reachable from a URL'));
        }
        if ($uri1->toUrl() !== $url2) {
            Q_Dispatcher::forward($uri2);
            return;
            // we don't really need this, but it's here anyway
        }
    }
    $params2 = compact('errors', 'exception', 'errors_array', 'exception_array');
    if (Q::eventStack('Q/response')) {
        // Errors happened while rendering response. Just render errors view.
        return Q::view('Q/errors.php', $params2);
    }
    if (!$startedResponse) {
        try {
            // Try rendering the response, expecting it to
            // display the errors along with the rest.
            $ob = new Q_OutputBuffer();
            Q::event('Q/response', $params2);
            $ob->endFlush();
            return;
        } catch (Exception $e) {
            if (get_class($e) === 'Q_Exception_DispatcherForward') {
                throw $e;
                // if forwarding was requested, do it
                // for all other errors, continue trying other things
            }
            $output = $ob->getClean();
        }
    }
    if ($errors) {
        // Try rendering the app's errors response, if any.
        $app = Q::app();
        if (Q::canHandle("{$app}/errors/response/content")) {
            Q_Dispatcher::forward("{$app}/errors");
        } else {
            echo Q::view("Q/errors.php", compact('errors'));
        }
    }
    if (!empty($e)) {
        return Q::event('Q/exception', array('exception' => $e));
    }
}
コード例 #17
0
ファイル: Dispatcher.php プロジェクト: dmitriz/Platform
 /**
  * @method errors
  * @static
  * @protected
  * @param {Exception} $exception
  * @param {string} $module
  * @param {string} [$partial_response=null]
  */
 protected static function errors($exception, $module, $partial_response = null)
 {
     self::$errors_occurred = true;
     $response_started = self::$response_started;
     $errors = Q_Response::getErrors();
     Q::$toolWasRendered = array();
     try {
         if (self::$handling_errors) {
             // We need to handle errors, but we
             // have already tried to do it.
             // Just show the errors view.
             Q::event('Q/errors/native', compact('errors', 'exception', 'partial_response', 'response_started'));
             return;
         }
         self::$handling_errors = true;
         if (Q::canHandle("{$module}/errors")) {
             /**
              * @event $module/errors
              * @param {Exception} exception
              * @param {string} module
              * @param {string} partial_response
              */
             Q::event("{$module}/errors", compact('errors', 'exception', 'partial_response', 'response_started'));
         } else {
             /**
              * @event Q/errors
              * @param {Exception} exception
              * @param {string} module
              * @param {string} partial_response
              */
             Q::event("Q/errors", compact('errors', 'exception', 'partial_response', 'response_started'));
         }
     } catch (Exception $e) {
         Q_Exception::rethrow($e, '');
         // may be for forwarding
         /**
          * @event Q/exception
          * @param {Exception} exception
          */
         Q::event('Q/exception', compact('exception'));
         // the original exception
     }
 }
コード例 #18
0
ファイル: Response.php プロジェクト: dmitriz/Platform
 /**
  * Gets the current content of a slot, if any.
  * If slot content is null, then raises an event
  * to try to fill the slot. If it is filled,
  * returns the content. Otherwise, returns null.
  * @method fillSlot
  * @static
  * @param {string|array} $slotName The name of the slot.
  * @param {boolean} [$default_slotName=null] If the slot named in $slotName returns null,
  *  the handler corresponding to the default slot will be called,
  *  passing it the requested slot's name in the 'slotName' parameter,
  *  and its value will be returned instead.
  *  Note: this does not fill the slot named $default_slotName!
  *  That is to say, the computed value is not saved, so that
  *  the slot's handler is called again if it is ever consulted again.
  * @param {string} [$prefix=null] Sets a prefix for the HTML ids of all the elements in the slot.
  * @return {string|null}
  */
 static function fillSlot($slotName, $default_slotName = null, $prefix = null)
 {
     if (isset(self::$slots[$slotName])) {
         return self::$slots[$slotName];
     }
     $prev_slotName = self::$slotName;
     self::$slotName = $slotName;
     if (isset($prefix)) {
         Q_Html::pushIdPrefix($prefix);
     }
     try {
         if (isset($default_slotName)) {
             if (!Q::canHandle("Q/response/{$slotName}")) {
                 /**
                  * @event Q/response/$default_slotName
                  * @param {string} slotName
                  * @return {string}
                  */
                 $result = Q::event("Q/response/{$default_slotName}", compact('slotName'));
                 if (isset(self::$slots[$slotName])) {
                     // The slot was already filled, while we were rendering it
                     // so discard the $result and return the slot's contents
                     return self::$slots[$slotName];
                 }
                 return self::$slots[$slotName] = $result;
             }
         }
         /**
          * @event Q/response/$slotName
          * @return {string}
          */
         $result = Q::event("Q/response/{$slotName}");
     } catch (Exception $e) {
         self::$slotName = $prev_slotName;
         if (isset($prefix)) {
             Q_Html::popIdPrefix();
         }
         throw $e;
     }
     self::$slotName = $prev_slotName;
     if (isset($prefix)) {
         Q_Html::popIdPrefix();
     }
     if (isset(self::$slots[$slotName])) {
         // The slot was already filled, while we were rendering it
         // so discard the $result and return the slot's contents
         return self::$slots[$slotName];
     }
     if (isset($result)) {
         self::setSlot($slotName, $result);
         return $result;
     }
     // Otherwise, render default slot
     if (!isset($default_slotName)) {
         return null;
     }
     /**
      * @event Q/response/$default_slotName
      * @param {string} slotName
      * @return {string}
      */
     return Q::event("Q/response/{$default_slotName}", compact('slotName'));
 }