Create "additionalJs" HBS helper

This commit is contained in:
Dmitriy Simushev 2014-10-09 13:25:17 +00:00
parent e320dcd1bb
commit bc45a6d3be
8 changed files with 163 additions and 84 deletions

View File

@ -28,9 +28,6 @@
// Initialize application
app.addInitializer(function(options){
// Store plugin options
Mibew.PluginOptions = options.plugins || {};
// Initialize Server
Mibew.Objects.server = new Mibew.Server(_.extend(
{'interactionType': MibewAPIChatInteraction},

View File

@ -51,9 +51,6 @@
// Initialize application
App.addInitializer(function(options){
// Store plugin options
Mibew.PluginOptions = options.plugins || {};
// Create some shortcuts
var objs = Mibew.Objects;
var models = Mibew.Objects.Models;

View File

@ -151,8 +151,26 @@ class AssetManager implements AssetManagerInterface
}
/**
* Triggers "pageAddJS" and "pageAddJSPluginOptions" events and prepares JS
* assets which are returned by plugins.
* Gets additional JS assets by triggering some events.
*
* Triggers "pageAddJS" and pass to the listeners an associative array with
* the following keys:
* - "request": {@link \Symfony\Component\HttpFoundation\Request}, a
* request instance. JavaScript files will be attached to the requested
* page.
* - "js": array of assets. Each asset can be either string with absolute
* JavaScript file URL or an array with "content" and "type" items. See
* {@link \Mibew\Asset\AssetManagerInterface::getJsAssets()} for details
* of their meaning. Modify this array to add or remove additional
* JavaScript files.
*
* Triggers "pageAddJSPluginOptions" and pass to the listeners an
* associative array with the following keys:
* - "request": {@link \Symfony\Component\HttpFoundation\Request}, a
* request instance. Plugins will work at the requested page.
* - "plugins": associative array, whose keys are plugins names and values
* are plugins options. Modify this array to add or change plugins
* options.
*
* @return array Assets list.
*/

View File

@ -26,6 +26,7 @@ use Mibew\Authentication\AuthenticationManagerAwareInterface;
use Mibew\Authentication\AuthenticationManagerInterface;
use Mibew\Cache\CacheAwareInterface;
use Mibew\Handlebars\HandlebarsAwareInterface;
use Mibew\Handlebars\Helper\AdditionalJsHelper;
use Mibew\Handlebars\Helper\AssetHelper;
use Mibew\Handlebars\Helper\CsrfProtectedRouteHelper;
use Mibew\Handlebars\Helper\RouteHelper;
@ -127,6 +128,9 @@ abstract class AbstractController implements
if ($handlebars->hasHelper('asset')) {
$handlebars->getHelper('asset')->setAssetUrlGenerator($manager->getUrlGenerator());
}
if ($handlebars->hasHelper('additionalJs')) {
$handlebars->getHelper('additionalJs')->setAssetManager($manager);
}
}
}
@ -283,6 +287,10 @@ abstract class AbstractController implements
array('CurrentStyle' => $style->getFilesPath())
)
);
$style->getHandlebars()->addHelper(
'additionalJs',
new AdditionalJsHelper($this->getAssetManager())
);
}
return $style;

View File

@ -0,0 +1,131 @@
<?php
/*
* This file is a part of Mibew Messenger.
*
* Copyright 2005-2014 the original author or authors.
*
* 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.
*/
namespace Mibew\Handlebars\Helper;
use Handlebars\Context;
use Handlebars\Helper as HelperInterface;
use Handlebars\SafeString;
use Handlebars\Template;
use Mibew\Asset\AssetManagerAwareInterface;
use Mibew\Asset\AssetManagerInterface;
/**
* A helper that generates additional JavaSctipts list from assets attached to
* Asset Manager.
*
* Example of usage:
* <code>
* {{additionalJs}}
* </code>
*/
class AdditionalJsHelper implements HelperInterface, AssetManagerAwareInterface
{
/**
* @var AssetManagerInterface|null
*/
protected $manager = null;
/**
* Class constructor.
*
* @param AssetUrlGeneratorInterface $manager An instance of Asset Manager.
*/
public function __construct(AssetManagerInterface $manager)
{
$this->manager = $manager;
}
/**
* {@inheritdoc}
*/
public function getAssetManager()
{
return $this->manager;
}
/**
* {@inheritdoc}
*/
public function setAssetManager(AssetManagerInterface $manager)
{
$this->manager = $manager;
}
/**
* {@inheritdoc}
*/
public function execute(Template $template, Context $context, $args, $source)
{
$generator = $this->getAssetManager()->getUrlGenerator();
$buffer = array();
foreach ($this->getAssetManager()->getJsAssets() as $asset) {
switch ($asset['type']) {
case AssetManagerInterface::ABSOLUTE_URL:
$buffer[] = $this->renderUrl($asset['content']);
break;
case AssetManagerInterface::RELATIVE_URL:
$buffer[] = $this->renderUrl($generator->generate($asset['content']));
break;
case AssetManagerInterface::INLINE:
$buffer[] = $this->renderContent($asset['content']);
break;
default:
throw new \RuntimeException(sprintf(
'Unknown asset type "%s"',
$asset['type']
));
}
}
return new SafeString(implode("\n", $buffer));
}
/**
* Renders URL of an asset.
*
* @param string $url URL of an asset.
* @return string HTML markup.
*/
protected function renderUrl($url)
{
return sprintf(
'<script src="%s"></script>',
safe_htmlspecialchars($url)
);
}
/**
* Renders content of an asset.
*
* @param string $content Content of an asset.
* @return string HTML markup.
*/
protected function renderContent($content)
{
return sprintf(
'<script>%s</script>',
$content
);
}
}

View File

@ -68,87 +68,17 @@ function get_additional_css(Request $request)
return implode("\n", $result);
}
/**
* Load additional JavaScript files, required by plugins, and build HTML code
* to include them
*
* Triggers 'pageAddJS' and pass listeners associative array with
* following keys:
* - 'request': {@link \Symfony\Component\HttpFoundation\Request}, a request
* instance. JavaScript files will be attached to the requested page.
* - 'js': array, with JavaScript files paths. Modify this array to add or
* remove additional JavaScript files.
*
* @param Request $request A Request instance.
* @return string HTML block of 'script' tags
*/
function get_additional_js(Request $request)
{
// Prepare event arguments array
$args = array(
'request' => $request,
'js' => array()
);
// Trigger event
$dispatcher = EventDispatcher::getInstance();
$dispatcher->triggerEvent('pageAddJS', $args);
// Build resulting css list
$result = array();
foreach ($args['js'] as $js) {
$result[] = '<script type="text/javascript" src="' . $js . '"></script>';
}
return implode("\n", $result);
}
/**
* Build Javascript code that contains initializing options for JavaScript
* plugins
*
* Triggers 'pageAddJSPluginOptions' and pass listeners associative array with
* following keys:
* - 'request': {@link \Symfony\Component\HttpFoundation\Request}, a request
* instance. Plugins will work at the requested page.
* - 'plugins': associative array, whose keys are plugins names and values are
* plugins options. Modify this array to add or change plugins options
*
* @param Request $request A Request instance.
* @return string JavaScript options block
*/
function get_js_plugin_options(Request $request)
{
// Prepare event arguments array
$args = array(
'request' => $request,
'plugins' => array()
);
// Trigger event
$dispatcher = EventDispatcher::getInstance();
$dispatcher->triggerEvent('pageAddJSPluginOptions', $args);
// Return encoded options
return json_encode($args['plugins']);
}
/**
* Get additional plugins data for specified page
*
* @param Request $request A Request instance.
* @return array Associative array of plugins data. It contains following keys:
* - 'additional_css': contains results of the 'get_additional_css function
* - 'additional_js': contains results of the 'get_additional_js' function
* - 'js_plugin_options': contains results of the 'get_js_plugin_options'
* function
*/
function get_plugins_data(Request $request)
{
return array(
'additional_css' => get_additional_css($request),
'additional_js' => get_additional_js($request),
'js_plugin_options' => get_js_plugin_options($request)
);
}

View File

@ -28,7 +28,7 @@
<!-- Add style scripts -->
<script type="text/javascript" src="{{asset "@CurrentStyle/js/compiled/scripts.js"}}"></script>
{{{additional_js}}}
{{additionalJs}}
<!-- Run application -->
<script type="text/javascript"><!--
@ -62,8 +62,7 @@
{{#if invitationOptions}}
invitationOptions: {{{invitationOptions}}},
{{/if}}
startFrom: '{{startFrom}}',
plugins: {{{js_plugin_options}}}
startFrom: '{{startFrom}}'
});
});
//--></script>

View File

@ -10,7 +10,7 @@
<script type="text/javascript" src="{{asset "js/compiled/users_app.js"}}"></script>
<!-- Plugins JavaScript files -->
{{{additional_js}}}
{{additionalJs}}
<script type="text/javascript"><!--
@ -48,8 +48,7 @@
trackedVisitorWindowParams: "{{[coreStyles.trackedVisitorWindowParams]}}",
banWindowParams: "{{[coreStyles.banWindowParams]}}",
inviteWindowParams: "{{[coreStyles.inviteWindowParams]}}"
},
plugins: {{{js_plugin_options}}}
}
});
});
//--></script>