This commit is contained in:
Simon Vieille 2015-03-03 18:51:20 +01:00
commit 543913101e
1233 changed files with 97467 additions and 0 deletions

4
.gitignore vendored Normal file
View file

@ -0,0 +1,4 @@
.svn
om/
map/
vendor/

43
composer.json Normal file
View file

@ -0,0 +1,43 @@
{
"name": "simmstein/trinity-bundles",
"license": "CC-BY",
"type": "symfony-bundle",
"description": "Trinity CMS Bundles",
"autoload": {
"psr-0": {
"": "src/"
}
},
"require": {
"php": ">=5.3.3",
"symfony/symfony": "2.3.*",
"doctrine/orm": "~2.2,>=2.2.3",
"doctrine/doctrine-bundle": "1.2.*",
"twig/extensions": "1.0.*",
"symfony/assetic-bundle": "2.3.*",
"symfony/swiftmailer-bundle": "2.3.*",
"symfony/monolog-bundle": "2.3.*",
"sensio/distribution-bundle": "2.3.*",
"sensio/framework-extra-bundle": "2.3.*",
"sensio/generator-bundle": "2.3.*",
"incenteev/composer-parameter-handler": "~2.0",
"propel/propel-bundle": "1.2.*",
"friendsofsymfony/user-bundle": "2.0.0-alpha1",
"jms/di-extra-bundle": "dev-master",
"jms/security-extra-bundle": "dev-master",
"knplabs/knp-menu": "dev-master",
"knplabs/knp-menu-bundle": "dev-master",
"white-october/pagerfanta-bundle": "dev-master",
"pagerfanta/pagerfanta": "dev-master",
"stfalcon/tinymce-bundle": "dev-master",
"kriswallsmith/assetic": "dev-master",
"symfony/assetic-bundle": "dev-master",
"simplethings/form-extra-bundle": "dev-master",
"willdurand/propel-typehintable-behavior": "dev-master",
"excelwebzone/zend-search": "dev-master",
"zendframework/zendgdata": "dev-master",
"glorpen/propel-bundle": "1.2.*",
"knplabs/knp-snappy-bundle": "dev-master"
},
"minimum-stability": "stable"
}

View file

@ -0,0 +1,61 @@
<?php
namespace Trinity\Bundle\AdminBreadcrumbsBundle\DependencyInjection;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
/**
* This is the class that validates and merges configuration from your app/config files
*
* To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html#cookbook-bundles-extension-config-class}
*/
class Configuration implements ConfigurationInterface
{
/**
* {@inheritDoc}
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('trinity_admin_breadcrumbs');
$rootNode->children()
->variableNode('routename')
->defaultValue('TrinityDashBoardBundle_index')
->end()
->arrayNode('default_params')
->useAttributeAsKey('name')
->prototype('variable')
->end()
->end()
->arrayNode('ignore_route_patterns')
->defaultValue(array(
'(.*)Node(.*)',
'(.*)MediaTinyMCEAdmin(.*)',
// '(.*)Page(.*)',
'^_(.*)', # ignore symfony routes
'^fos_user_(.*)',
'^trinity_user_(.*)',
'(.*)xhr(.*)'
))
->prototype('scalar')->end()
->end()
->arrayNode('required_uri_patterns')
->defaultValue(array(
'^/admin(.*)'
))
->prototype('scalar')->end()
->end()
->end()
;
return $treeBuilder;
}
}

View file

@ -0,0 +1,38 @@
<?php
namespace Trinity\Bundle\AdminBreadcrumbsBundle\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;
/**
* This is the class that loads and manages your bundle configuration
*
* To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html}
*/
class TrinityAdminBreadcrumbsExtension extends Extension
{
/**
* {@inheritDoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.xml');
$container->getDefinition('breadcrumb.manager')
->replaceArgument(1, $config['routename'])
->replaceArgument(2, $config['default_params'])
;
$container->getDefinition('breadcrumb.request_listener')
->replaceArgument(1, $config['ignore_route_patterns'])
->replaceArgument(2, $config['required_uri_patterns'])
;
}
}

View file

@ -0,0 +1,42 @@
<?php
namespace Trinity\Bundle\AdminBreadcrumbsBundle\Listener;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use \Trinity\Bundle\AdminBreadcrumbsBundle\Model\BreadcrumbManager;
class RequestListener
{
protected $breadcrumbManager;
protected $ignoreRoutePatterns;
public function __construct(BreadcrumbManager $manager, array $ignore_route_patterns, array $required_uri_patterns)
{
$this->breadcrumbManager = $manager;
$this->ignoreRoutePatterns = $ignore_route_patterns;
$this->requiredUriPatterns = $required_uri_patterns;
}
public function onKernelRequest(GetResponseEvent $event)
{
foreach ($this->requiredUriPatterns as $uriPattern) {
if (!preg_match(sprintf('#%s#s', $uriPattern), $event->getRequest()->getPathInfo())) {
return false;
}
}
if (preg_match('`jsTranslations`', $event->getRequest()->getPathInfo())) {
return false;
}
foreach ($this->ignoreRoutePatterns as $routePattern) {
if (preg_match(sprintf('#%s#s', $routePattern), $event->getRequest()->get('_route'))) {
return false;
}
}
$this->breadcrumbManager->buildCrudBreadcrumbFor($event->getRequest());
return true;
}
}

View file

@ -0,0 +1,100 @@
<?php
namespace Trinity\Bundle\AdminBreadcrumbsBundle\Model;
use \Trinity\Bundle\AdminBreadcrumbsBundle\Model\BreadcrumbItem;
class Breadcrumb implements \Iterator, \ArrayAccess, \Countable
{
private $items = array();
public function add($text, $url, $helper = "")
{
$item = new BreadcrumbItem($text, $url, $helper);
$this->items[] = $item;
return $this;
}
public function addItem(BreadcrumbItem $item, $index = null)
{
if (null === $index) {
$this->items[] = $item;
} else {
$this->items[$index] = $item;
}
return $this;
}
public function clear()
{
$this->items = array();
return $this;
}
public function getLastItem()
{
$keys = array_keys($this->items);
return $this->items[array_pop($keys)];
}
public function getFirstItem()
{
$keys = array_keys($this->items);
return $this->items[array_shift($keys)];
}
public function current()
{
return current($this->items);
}
public function next()
{
return next($this->items);
}
public function key()
{
return key($this->items);
}
public function valid()
{
return key($this->items) !== null;
}
public function rewind()
{
return reset($this->items);
}
public function offsetExists($offset)
{
return isset($this->items[$offset]);
}
public function offsetGet($offset)
{
return isset($this->items[$offset]) ? $this->items[$offset] : null;
}
public function offsetSet($offset, $value)
{
$this->items[$offset] = $value;
}
public function offsetUnset($offset)
{
unset($this->items[$offset]);
}
public function count()
{
return count($this->items);
}
}

View file

@ -0,0 +1,53 @@
<?php
namespace Trinity\Bundle\AdminBreadcrumbsBundle\Model;
class BreadcrumbItem
{
private $url;
private $text;
private $helper;
public function __construct($text, $url, $helper = null)
{
$this->url = $url;
$this->text = $text;
$this->helper = $helper;
}
public function setText($text)
{
$this->text = $text;
return $this;
}
public function getText()
{
return $this->text;
}
public function setUrl($url)
{
$this->url = $url;
return $this;
}
public function getUrl()
{
return $this->url;
}
public function setHelper($helper)
{
$this->helper = $helper;
return $this;
}
public function getHelper()
{
return $this->helper;
}
}

View file

@ -0,0 +1,116 @@
<?php
namespace Trinity\Bundle\AdminBreadcrumbsBundle\Model;
use \Symfony\Component\Routing\RouterInterface;
class BreadcrumbManager
{
protected $root_item = null;
protected $breadcrumb;
protected $router;
protected $default_params;
protected $default_routename;
public function __construct(RouterInterface $router, $default_routename, array $default_params)
{
$this->router = $router;
$this->default_routename = $default_routename;
$this->default_params = $default_params;
}
public function initBreadcrumb()
{
$this->breadcrumb = new Breadcrumb();
$this->breadcrumb->addItem($this->getRootItem());
}
public function get()
{
if ($this->breadcrumb === null) {
$this->initBreadcrumb();
}
return $this->breadcrumb;
}
public function setRootItem(BreadcrumbItem $root_item)
{
$this->root_item = $root_item;
}
public function getRootItem()
{
if ($this->root_item === null) {
$this->root_item = new BreadcrumbItem(
'trinity.dashboard.index.title',
$this->router->generate($this->default_routename, $this->default_params),
'trinity.dashboard.index.helper'
);
}
return $this->root_item;
}
public function buildCrudBreadcrumbFor($request)
{
$routename = $request->get('_route');
if ($routename == $this->default_routename) {
return;
}
if (preg_match('`^.*index`',$routename)) {
$this->get()->addItem($this->getItemFor($request));
return;
}
$this->get()->addItem($this->getItemFor($request,true));
$this->get()->addItem($this->getItemFor($request));
}
public function getItemFor($request, $index = false)
{
$key = $this->generateKey($request, $index);
$route = $this->generateRoute($request, $index);
$item = new BreadcrumbItem(
sprintf('%s.title', $key),
$route,
sprintf('%s.helper', $key)
);
return $item;
}
private function generateRoute($request, $index = false)
{
if ($index) {
$route = preg_replace('`_.*$`','_index', $request->get('_route'));
return $this->router->generate($route);
}
return $this->router->generate($request->get('_route'), $request->get('_route_params'));
}
private function generateKey($request, $index = false)
{
$datas = explode('::', $request->get('_controller'));
$action = ($index) ? 'index' : str_replace('Action', '', $datas[1]);
$path = explode('\\', $datas[0]);
if (count($path) < 4) {
return null;
}
$firm = strtolower($path[0]);
$bundle = strtolower(str_replace('Bundle', '', $path[count($path)-3]));
$controller = strtolower(str_replace('Controller', '', end($path)));
return sprintf('%s.%s.%s.%s', $firm, $bundle, $controller, $action);
}
}

View file

@ -0,0 +1,34 @@
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="admin.manager.breadcrumb.class">Trinity\Bundle\AdminBreadcrumbsBundle\Model\BreadcrumbManager</parameter>
<parameter key="breadcrumb.request_listener.class">Trinity\Bundle\AdminBreadcrumbsBundle\Listener\RequestListener</parameter>
</parameters>
<services>
<service id="breadcrumb.manager" class="%admin.manager.breadcrumb.class%">
<argument type="service" id="router"/>
<argument />
<argument />
</service>
<service id="breadcrumb.request_listener" class="%breadcrumb.request_listener.class%" scope="request">
<tag name="kernel.event_listener" event="kernel.request" method="onKernelRequest" priority="-5" />
<argument type="service" id="breadcrumb.manager" />
<argument />
<argument />
</service>
<service id="breadcrumb.twig.extension" class="Trinity\Bundle\AdminBreadcrumbsBundle\Twig\Extension\BreadcrumbExtension" public="false">
<tag name="twig.extension" />
<argument type="service" id="breadcrumb.manager" />
</service>
</services>
</container>

View file

@ -0,0 +1,137 @@
trinity:
dashboard:
index:
title: 'Tableau de bord'
helper: ~
varseditor:
varsadmin:
index:
title: 'Éditeur de variables globales'
contentmanager:
pageadmin:
index:
title: 'Gestion des pages'
new:
title: 'Nouvelle page'
edit:
title: 'Édition'
processEditMetas:
title: 'Édition des données SEO'
processEditBlocks:
title: 'Édition du contenu'
processEditPerms:
title: 'Édition des paramètres'
processEditSitemap:
title: 'Édition du sitemap'
navigationadmin:
index:
title: 'Gestion des navigations'
helper: 'Une navigation correspond à un site et son arborescence.'
new:
title: 'Nouveau'
edit:
title: 'Édition'
menuadmin:
index:
title: 'Gestion des menus'
new:
title: 'Nouveau'
edit:
title: 'Édition'
editorialblock:
editorialblockadmin:
index:
title: 'Gestion des blocs éditoriaux'
new:
title: 'Nouveau'
edit:
title: 'Édition'
media:
mediaadmin:
index:
title: 'Gestion des médias'
new:
title: 'Nouveau'
edit:
title: 'Édition'
typeadmin:
index:
title: 'Gestion des types'
new:
title: 'Nouveau'
edit:
title: 'Édition'
categoryadmin:
index:
title: 'Gestion des catégories'
new:
title: 'Nouveau'
edit:
title: 'Édition'
user:
groupadmin:
index:
title: "Gestion des groupes"
new:
title: "Nouveau"
edit:
title: "Édition"
useradmin:
index:
title: "Gestion des utilisateurs"
new:
title: "Nouveau"
edit:
title: "Édition"
userlogadmin:
index:
title: 'Logs des utilisateurs'
edit:
title: 'Édition'
contact:
contactadmin:
index:
title: "Prises de contact"
new:
title: "Nouveau"
edit:
title: "Édition"
newsletter:
newsletteradmin:
index:
title: "Newsletter"
new:
title: "Nouveau"
edit:
title: "Édition"
modeladmin:
index:
title: "Modèle de newsletter"
new:
title: "Nouveau"
edit:
title: "Édition"
notification:
notificationadmin:
index:
title: "Notifications"
templateadmin:
index:
title: "Templates des notifications"
new:
title: "Nouveau"
edit:
title: "Édition"

View file

@ -0,0 +1,23 @@
<div id="breadcrumb">
{% set helper = breadcrumb.lastItem.helper|trans({}, 'TrinityAdminBreadcrumbsBundle') %}
{% if helper != breadcrumb.lastItem.helper and helper %}
<div class="help">
{{ helper }}
<i class="icon-info-sign"></i>
</div>
{% endif %}
<ul>
{% for item in breadcrumb %}
{% if breadcrumb.lastItem == item %}
<li class="last-sep"></li>
{% elseif breadcrumb.firstItem != item %}
<li class="sep"></li>
{% endif %}
<li><a href="{{ item.url }}">{{ item.text|trans({}, 'TrinityAdminBreadcrumbsBundle') }}</a></li>
{% endfor %}
</ul>
</div>

View file

@ -0,0 +1,9 @@
<?php
namespace Trinity\Bundle\AdminBreadcrumbsBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class TrinityAdminBreadcrumbsBundle extends Bundle
{
}

View file

@ -0,0 +1,51 @@
<?php
namespace Trinity\Bundle\AdminBreadcrumbsBundle\Twig\Extension;
use \Trinity\Bundle\AdminBreadcrumbsBundle\Model\BreadcrumbManager;
class BreadcrumbExtension extends \Twig_Extension
{
private $environment;
private $resources;
protected $breadcrumbManager;
public function __construct(BreadcrumbManager $BreadcrumbManager)
{
$this->breadcrumbManager = $BreadcrumbManager;
}
public function initRuntime(\Twig_Environment $environment)
{
$this->environment = $environment;
}
public function getName()
{
return 'breadcrumb_extension';
}
public function getFunctions()
{
return array(
'render_admin_breadcrumb' => new \Twig_Function_Method($this, 'renderAdminBreadcrumb', array('is_safe' => array('html'))),
);
}
public function renderAdminBreadcrumb()
{
$breadcrumb = $this->breadcrumbManager->get();
return $this->render('TrinityAdminBreadcrumbsBundle:Utils:breadcrumb.html.twig',array('breadcrumb' => $breadcrumb));
}
public function render($template, array $parameters = array())
{
if (!isset($this->resources[$template])) {
$this->resources[$template] = $this->environment->loadTemplate($template);
}
return $this->resources[$template]->render($parameters);
}
}

View file

@ -0,0 +1,741 @@
<?php
namespace Trinity\Bundle\AdminBundle\Command;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\Output;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Sensio\Bundle\GeneratorBundle\Command\Helper\DialogHelper;
use Symfony\Component\Filesystem\Exception\IOException;
use Sensio\Bundle\GeneratorBundle\Command\Validators;
class GenerateCrudCommand extends ContainerAwareCommand
{
/**
* @see Command
*/
protected function configure()
{
$this
->setDefinition(array(
new InputOption('namespace', '', InputOption::VALUE_REQUIRED, 'The namespace of the bundle to create'),
new InputOption('bundle', '', InputOption::VALUE_REQUIRED, 'The bundle to generate model classes from'),
))
->setDescription('Generate basics files for the CRUD')
->setHelp(<<<EOT
EOT
)
->setName('generate:crud')
;
}
/**
* @see Command
*
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$dialog = $this->getDialogHelper();
$filesystem = $this->getContainer()->get('filesystem');
if ($input->isInteractive()) {
if (!$dialog->askConfirmation($output, $dialog->getQuestion('Do you confirm generation', 'yes', '?'), true)) {
$output->writeln(
array(
'',
'<error>Command aborted</error>',
''
)
);
return 1;
}
}
$dialog->writeSection($output, 'Welcome to the CRUD generation!');
/* ------------------------------------------ */
$output->writeln(
array(
'',
'<info>Help:</info>',
' Use <comment> \ </comment> for the namespace delimiter to avoid any problem.',
'',
' You can find the bundle name in the file <comment>app/AppKernel.php</comment> without <comment>()</comment>',
'',
)
);
$namespace = $dialog->askAndValidate(
$output,
$dialog->getQuestion('Bundle namespace', $input->getOption('namespace')),
array('Sensio\Bundle\GeneratorBundle\Command\Validators', 'validateBundleNamespace'),
false,
$input->getOption('namespace')
);
$input->setOption('namespace', $namespace);
$bundle = $dialog->askAndValidate(
$output,
$dialog->getQuestion('Bundle name', $input->getOption('bundle')),
array('Sensio\Bundle\GeneratorBundle\Command\Validators', 'validateBundleName'),
false,
$input->getOption('bundle')
);
$input->setOption('bundle', $bundle);
$kernel = $this->getContainer()->get('kernel');
$kernel->getBundle($bundle);
$namespace_explode = explode("\\",$namespace);
/* ------------------------------------------ */
// target dir
$path = dirname($this->getContainer()->getParameter('kernel.root_dir')).'/src'.DIRECTORY_SEPARATOR;
$path.= implode(DIRECTORY_SEPARATOR, $namespace_explode);
if (!$filesystem->exists($path)) {
$output->writeln(array('','<error>Command aborted. The directory '.$path.' doesn\'t exist.</error>',''));
return 1;
}
/* ------------------------------------------ */
$errors = array();
$runner = $dialog->getRunner($output, $errors);
/* ------------------------------------------ */
$output->writeln(array('','Step 1: <info>Generate CrudConfiguration</info>',''));
$model = str_replace($namespace_explode[0], '', $bundle);
$model = str_replace('Bundle','',$model);
$model = $dialog->ask($output, $dialog->getQuestion('Model', $model, ':'), $model);
$classNameConfiguration = $model.'CrudConfiguration';
$nameSpaceConfiguration = $namespace.'\Configuration';
$modelPeer = $model.'Peer';
$modelQuery = $model.'Query';
$routePrefix = $bundle.$model.'Admin';
$formNamespace = '';
$modelNamespace = '';
$class = '';
foreach ($namespace_explode as $dir) {
$formNamespace .= $dir."\\\\";
$modelNamespace .= $dir."\\\\";
$class .= $dir."\\";
}
$formNamespace .= 'Form\\Type';
$modelNamespace .= 'Model';
$class .= 'Model\\'.$model;
$formEditNew = $model.'Type';
$formFilter = $model.'FilterType';
$maxPerPage = $dialog->askAndValidate(
$output,
$dialog->getQuestion('Max per page', 20, ':'),
function ($answer) {
if (!is_numeric($answer)) {
throw new \RunTimeException(
'The value must be an integer'
);
}
return (int) $answer;
},
false,
20
);
$rankable = $dialog->askConfirmation(
$output,
$dialog->getQuestion('Rankable', 'no', ':'),
false
);
$order = null;
if ($rankable) {
$order = $dialog->select($output, $dialog->getQuestion('Rank order','ASC'), array('ASC', 'DESC'), 0);
}
$rankable = !$rankable ? 'false' : 'true';
$contentConfiguration = "<?php
namespace ".$nameSpaceConfiguration.";
class ".$classNameConfiguration." extends \\Trinity\\Bundle\\AdminBundle\\Configuration\\CrudConfiguration
{
public function __construct()
{
\$this
->setModelNamespace('".$modelNamespace."')
->setModel('".$model."')
->setModelPeer('".$modelPeer."')
->setModelQuery('".$modelQuery."')
->setRoutePrefix('".$routePrefix."')
->setFormNamespace('".$formNamespace."')
->setFormEdit('".$formEditNew."')
->setFormFilter('".$formFilter."')
->setFormNew('".$formEditNew."')
->setFieldsets(array(
'' => array(
'*',
),
))
->setMaxPerPage(".$maxPerPage.")
->setRankable(".$rankable.")";
$orderRankable = array(0 => 'ASC', 1 => 'DESC');
if ($order) {
$contentConfiguration .= "
->setSort('orderByRank', \\Criteria::".$orderRankable[$order].")
";
}
$contentConfiguration .= "
->setListTitle('".$model."')
->setNewTitle('New ".strtolower($model)."')
->setEditTitle('Edition of \"%id%\"')
// Listing:
// ->setFieldTemplate('visible', 'TrinityAdminBundle:BaseAdmin:bool.html.twig')
// ->setDisplayFields(array(
//
// ))
// ->setFieldname('foo', 'bar')
;
}
}
";
//demande si ok ?
$output->writeln($contentConfiguration);
if ($input->isInteractive()) {
if (!$dialog->askConfirmation($output, $dialog->getQuestion('Do you agree', 'yes', '?'), true)) {
$output->writeln(
array(
'',
'<error>Command aborted</error>',
''
)
);
return 1;
}
}
// on regarde si le dossier configuration existe
$pathConfiguration = $path.DIRECTORY_SEPARATOR.'Configuration';
$configurationFile = $pathConfiguration.DIRECTORY_SEPARATOR.$classNameConfiguration.'.php';
try {
$filesystem->mkdir($pathConfiguration, 0777);
} catch (\IOException $e) {
$output->writeln(
array(
'',
'<error>$e</error>',
''
)
);
return 1;
}
if ($filesystem->exists($configurationFile)) {
$output->writeln(
array(
'',
'<info>The file '.$configurationFile.'</info> already exists.',
''
)
);
if ($input->isInteractive()) {
if ($dialog->askConfirmation($output, $dialog->getQuestion('Do you want to replace it', 'no', '?'), false)) {
$filesystem->remove($configurationFile);
$output->writeln(
array(
'',
'File <info>'.$configurationFile.'</info> <error>REMOVED</error>',
''
)
);
try {
$filesystem->touch($configurationFile, 0777);
file_put_contents($configurationFile, $contentConfiguration);
} catch (\IOException $e) {
$output->writeln(
array(
'',
'<error>$e</error>',
''
)
);
return 1;
}
}
}
} else {
try {
file_put_contents($configurationFile, $contentConfiguration);
} catch (\IOException $e) {
$output->writeln(
array(
'',
'<error>$e</error>',
''
)
);
return 1;
}
}
$output->writeln(array('', 'Generating the CRUD configuration: <info>OK</info>',''));
/* ------------------------------------------ */
$output->writeln(array('','Step 2: <info>Generate Controller</info>',''));
if ($input->isInteractive()) {
if (!$dialog->askConfirmation($output, $dialog->getQuestion('Continue', 'yes', '?'), true)) {
$output->writeln(
array(
'',
'<error>Command aborted</error>',
''
)
);
return 1;
}
}
$classNameController = $model.'AdminController';
$nameSpaceController = $namespace.'\Controller';
$contentController = '<?php
namespace '.$nameSpaceController.';
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Trinity\Bundle\AdminBundle\Controller\BaseAdminController;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Component\HttpFoundation\Request;
use '.$nameSpaceConfiguration.'\\'.$classNameConfiguration.' as CrudConfiguration;
/**
* @Route("/admin/'.strtolower($model).'")
*/
class '.$classNameController.' extends BaseAdminController
{
public function __construct()
{
$this->configuration = new CrudConfiguration();
}
/**
* @Route("/{page}", name="'.$routePrefix.'_index", defaults={"page" = "1"}, requirements={"page" = "\d+"})
* @Template()
*/
public function indexAction($page, Request $request)
{
return parent::indexAction($page, $request);
}
/**
* @Route("/new", name="'.$routePrefix.'_new")
* @Template()
*/
public function newAction(Request $request)
{
return parent::newAction($request);
}
/**
* @Route("/edit/{id}", name="'.$routePrefix.'_edit")
* @Template()
* @ParamConverter("object", class="'.$class.'")
*/
public function editAction($object, Request $request)
{
return parent::editAction($object, $request);
}
/**
* @Route("/remove/{id}/{token}", name="'.$routePrefix.'_remove")
* @Template()
* @ParamConverter("object", class="'.$class.'")
*/
public function removeAction($object, $token, Request $request)
{
return parent::removeAction($object, $token, $request);
}
/**
* @Route("/batch", name="'.$routePrefix.'_batch")
* @Template()
* @Method({"POST"})
*/
public function batchAction(Request $request)
{
return parent::batchAction($request);
}
/**
* @Route("/filter/clear", name="'.$routePrefix.'_filter_clear")
* @Template()
*/
public function clearFilterAction(Request $request)
{
return parent::clearFilterAction($request);
}';
if ($rankable) {
$contentController .= '
/**
* @Route("/rank", name="'.$routePrefix.'_rank")
* @Template("TrinityAdminBundle:BaseAdmin:rank.html.twig")
* @Method({"POST"})
*/
public function rankAction(Request $request)
{
return parent::rankAction($request);
}';
}
$contentController .= '
}
';
$output->writeln($contentController);
if ($input->isInteractive()) {
if (!$dialog->askConfirmation($output, $dialog->getQuestion('Are you agree', 'yes', '?'), true)) {
$output->writeln(
array(
'',
'<error>Command aborted</error>',
''
)
);
return 1;
}
}
// on regarde si le dossier configuration existe
$pathController = $path.DIRECTORY_SEPARATOR.'Controller';
$controllerFile = $pathController.DIRECTORY_SEPARATOR.$classNameController.'.php';
try {
$filesystem->mkdir($pathController, 0777);
} catch (\IOException $e) {
$output->writeln(
array(
'',
'<error>$e</error>',
''
)
);
return 1;
}
if ($filesystem->exists($controllerFile)) {
$output->writeln(
array(
'',
'<info>The file '.$controllerFile.'</info> already exists.',
''
)
);
if ($input->isInteractive()) {
if ($dialog->askConfirmation($output, $dialog->getQuestion('Do you want to replace it', 'no', '?'), false)) {
$filesystem->remove($controllerFile);
$output->writeln(
array(
'',
'File <info>'.$controllerFile.'</info> <error>REMOVED</error>',
''
)
);
try {
$filesystem->touch($controllerFile, 0777);
file_put_contents($controllerFile, $contentController);
} catch (\IOException $e) {
$output->writeln(
array(
'',
'<error>$e</error>',
''
)
);
return 1;
}
}
}
} else {
try {
$filesystem->touch($controllerFile, 0777);
file_put_contents($controllerFile, $contentController);
} catch (\IOException $e) {
$output->writeln(
array(
'',
'<error>$e</error>',
''
)
);
return 1;
}
}
$output->writeln(array('', 'Generating the file Controller: <info>OK</info>',''));
/* ------------------------------------------ */
$output->writeln(array('','Step 3: <info>Generate views</info>',''));
$pathViews = $path.DIRECTORY_SEPARATOR.'Resources'.DIRECTORY_SEPARATOR.'views'.DIRECTORY_SEPARATOR.$model.'Admin';
try {
$filesystem->mkdir($pathViews, 0777);
} catch (\IOException $e) {
$output->writeln(
array(
'',
'<error>$e</error>',
''
)
);
return 1;
}
// test des fichiers de vues
if ($filesystem->exists($pathViews.DIRECTORY_SEPARATOR.'index.html.twig')) {
$output->writeln(
array(
'',
'<info>The file '.$pathViews.DIRECTORY_SEPARATOR.'index.html.twig</info> already exists.',
''
)
);
if ($input->isInteractive()) {
if ($dialog->askConfirmation($output, $dialog->getQuestion('Do you want to replace it', 'no', '?'), false)) {
$filesystem->remove($pathViews.DIRECTORY_SEPARATOR.'index.html.twig');
$output->writeln(
array(
'',
'File <info>'.$pathViews.DIRECTORY_SEPARATOR.'index.html.twig</info> <error>REMOVED</error>',
''
)
);
try {
$filesystem->touch($pathViews.DIRECTORY_SEPARATOR.'index.html.twig', 0777);
file_put_contents($pathViews.DIRECTORY_SEPARATOR.'index.html.twig', '{% extends "TrinityAdminBundle:BaseAdmin:index.html.twig" %}');
} catch (\IOException $e) {
$output->writeln(
array(
'',
'<error>$e</error>',
''
)
);
return 1;
}
}
}
} else {
try {
$filesystem->touch($pathViews.DIRECTORY_SEPARATOR.'index.html.twig', 0777);
file_put_contents($pathViews.DIRECTORY_SEPARATOR.'index.html.twig', '{% extends "TrinityAdminBundle:BaseAdmin:index.html.twig" %}');
} catch (\IOException $e) {
$output->writeln(
array(
'',
'<error>$e</error>',
''
)
);
return 1;
}
}
if ($filesystem->exists($pathViews.DIRECTORY_SEPARATOR.'edit.html.twig')) {
$output->writeln(
array(
'',
'<info>The file '.$pathViews.DIRECTORY_SEPARATOR.'edit.html.twig</info> already exists.',
''
)
);
if ($input->isInteractive()) {
if ($dialog->askConfirmation($output, $dialog->getQuestion('Do you want to replace it', 'no', '?'), false)) {
$filesystem->remove($pathViews.DIRECTORY_SEPARATOR.'edit.html.twig');
$output->writeln(
array(
'',
'File <info>'.$pathViews.DIRECTORY_SEPARATOR.'edit.html.twig</info> <error>REMOVED</error>',
''
)
);
try {
$filesystem->touch($pathViews.DIRECTORY_SEPARATOR.'edit.html.twig', 0777);
file_put_contents($pathViews.DIRECTORY_SEPARATOR.'edit.html.twig', '{% extends "TrinityAdminBundle:BaseAdmin:edit.html.twig" %}');
} catch (\IOException $e) {
$output->writeln(
array(
'',
'<error>$e</error>',
''
)
);
return 1;
}
}
}
} else {
try {
$filesystem->touch($pathViews.DIRECTORY_SEPARATOR.'edit.html.twig', 0777);
file_put_contents($pathViews.DIRECTORY_SEPARATOR.'edit.html.twig', '{% extends "TrinityAdminBundle:BaseAdmin:edit.html.twig" %}');
} catch (\IOException $e) {
$output->writeln(
array(
'',
'<error>$e</error>',
''
)
);
return 1;
}
}
if ($filesystem->exists($pathViews.DIRECTORY_SEPARATOR.'new.html.twig')) {
$output->writeln(
array(
'',
'<info>The file '.$pathViews.DIRECTORY_SEPARATOR.'new.html.twig</info> already exists.',
''
)
);
if ($input->isInteractive()) {
if ($dialog->askConfirmation($output, $dialog->getQuestion('Do you want to replace it', 'no', '?'), false)) {
$filesystem->remove($pathViews.DIRECTORY_SEPARATOR.'new.html.twig');
$output->writeln(
array(
'',
'File <info>'.$pathViews.DIRECTORY_SEPARATOR.'new.html.twig</info> <error>REMOVED</error>',
''
)
);
try {
$filesystem->touch($pathViews.DIRECTORY_SEPARATOR.'new.html.twig', 0777);
file_put_contents($pathViews.DIRECTORY_SEPARATOR.'new.html.twig', '{% extends "TrinityAdminBundle:BaseAdmin:new.html.twig" %}');
} catch (\IOException $e) {
$output->writeln(
array(
'',
'<error>$e</error>',
''
)
);
return 1;
}
}
}
} else {
try {
$filesystem->touch($pathViews.DIRECTORY_SEPARATOR.'new.html.twig', 0777);
file_put_contents($pathViews.DIRECTORY_SEPARATOR.'new.html.twig', '{% extends "TrinityAdminBundle:BaseAdmin:new.html.twig" %}');
} catch (\IOException $e) {
$output->writeln(
array(
'',
'<error>$e</error>',
''
)
);
return 1;
}
}
$output->writeln(array('', 'Generating views: <info>OK</info>',''));
/* ------------------------------------------ */
$dialog->writeGeneratorSummary($output, $errors);
}
protected function getDialogHelper()
{
$dialog = $this->getHelperSet()->get('dialog');
if (!$dialog || get_class($dialog) !== 'Sensio\Bundle\GeneratorBundle\Command\Helper\DialogHelper') {
$this->getHelperSet()->set($dialog = new DialogHelper());
}
return $dialog;
}
}

View file

@ -0,0 +1,740 @@
<?php
namespace Trinity\Bundle\AdminBundle\Configuration;
use Trinity\Bundle\AdminBundle\Exception as BaseAdminException;
class CrudConfiguration
{
protected $modelNamespace = null;
protected $model = null;
protected $modelPeer = null;
protected $modelQuery = null;
protected $routePrefix = null;
protected $formNamespace = null;
protected $formEdit = null;
protected $formNew = null;
protected $formFilter = null;
protected $formEditOptions = array();
protected $formNewOptions = array();
protected $formFilterOptions = array();
protected $fieldsTemplates = array();
protected $fieldsHelpers = array();
protected $displayFields = array();
protected $displayFieldsAttrs = array();
protected $fieldsets = array();
protected $fieldsetsView = 'fieldset';
protected $fieldsnames = array();
protected $filterDisplayFields = array();
protected $filtersMethods = array();
protected $filtersTemplates = array();
protected $filterNamespace = null;
protected $filter = null;
protected $filterValue = null;
protected $listTitle = null;
protected $editTitle = null;
protected $newTitle = null;
protected $maxPerPage = 10;
protected $currentPage = 1;
protected $sort = null;
protected $sortOrder = \Criteria::ASC;
protected $rankable = false;
protected $i18nCultures = array();
protected $i18n = false;
protected $storageNamespace = null;
protected $batchActions = true;
protected $contextMenu = true;
protected $collections = array();
protected $export = false;
protected $exportFormats = array();
protected $redirectIfOneResult = true;
protected $indexListActions = array(
'edit' => 'TrinityAdminBundle:BaseAdmin:listEdit.html.twig',
'remove' => 'TrinityAdminBundle:BaseAdmin:listRemove.html.twig',
);
protected $indexActions = array(
'new' => 'TrinityAdminBundle:BaseAdmin:indexNew.html.twig',
);
public function setExport($export, array $formats = array('XML', 'CSV', 'JSON', 'YAML'))
{
$this->export = (bool) $export;
$this->exportFormats = $formats;
return $this;
}
public function getExport()
{
return $this->export;
}
public function setExportFormats(array $exportFormats)
{
$this->exportFormats = $exportFormats;
return $this;
}
public function getExportFormats()
{
return $this->exportFormats;
}
private function formatNamespace($namespace)
{
if (substr($namespace, strlen($namespace)-1) !== '\\') {
$namespace .= '\\';
}
return $namespace;
}
public function setIndexListAction($actionName, $template = 'TrinityAdminBundle:BaseAdmin:listDefault.html.twig')
{
$this->indexListActions[$actionName] = $template;
return $this;
}
public function setIndexListActions(array $actions)
{
$this->indexListActions = $actions;
return $this;
}
public function removeIndexAction($action)
{
if (isset($this->indexActions[$action])) {
unset($this->indexActions[$action]);
}
return $this;
}
public function removeIndexListAction($action)
{
if (isset($this->indexListActions[$action])) {
unset($this->indexListActions[$action]);
}
return $this;
}
public function getIndexListActions()
{
return $this->indexListActions;
}
public function getIndexListAction($action)
{
return isset($this->indexListActions[$action]) ? $this->indexListActions[$action] : null;
}
public function setIndexAction($actionName,$template)
{
$this->indexActions[$actionName] = $template;
return $this;
}
public function setIndexActions(array $actions)
{
$this->indexActions = $actions;
return $this;
}
public function getIndexActions()
{
return $this->indexActions;
}
public function getIndexAction($action)
{
return isset($this->indexActions[$action]) ? $this->indexActions[$action] : null;
}
public function setContextMenu($contextMenu)
{
$this->contextMenu = (bool) $contextMenu;
return $this;
}
public function getContextMenu()
{
return $this->contextMenu;
}
public function setModelNamespace($modelNamespace)
{
$this->modelNamespace = $this->formatNamespace($modelNamespace);
return $this;
}
public function setFormNamespace($formNamespace)
{
$this->formNamespace = $this->formatNamespace($formNamespace);
return $this;
}
public function getFormNamespace()
{
return $this->formNamespace;
}
public function setFilterNamespace($filterNamespace)
{
$this->filterNamespace = $this->formatNamespace($filterNamespace);
return $this;
}
public function getFiltersTemplates()
{
return $this->filtersTemplates;
}
public function setBatchActions($batchActions)
{
$this->batchActions = (bool) $batchActions;
return $this;
}
public function getBatchActions()
{
return $this->batchActions;
}
public function getFilterNamespace()
{
return $this->filterNamespace ? $this->filterNamespace : $this->formNamespace;
}
public function setFieldsets(array $fieldsets, array $i18nFieldsets = array())
{
$this->fieldsets = $fieldsets;
return $this;
}
public function getFieldsets()
{
return $this->fieldsets;
}
public function setFieldsetsView($fieldsetsView)
{
$this->fieldsetsView = $fieldsetsView;
return $this;
}
public function getFieldsetsView()
{
return $this->fieldsetsView;
}
public function getFieldsnames()
{
return $this->fieldsnames;
}
public function setFieldname($fieldname, $name)
{
$this->fieldsnames[$fieldname] = $name;
return $this;
}
public function setMaxPerPage($maxPerPage)
{
if (is_integer($maxPerPage)) {
$this->maxPerPage = $maxPerPage;
}
return $this;
}
public function getMaxPerPage()
{
return $this->maxPerPage;
}
public function setCurrentPage($currentPage)
{
$this->currentPage = $currentPage;
return $this;
}
public function getCurrentPage()
{
return $this->currentPage;
}
public function setFilter($method, $value)
{
$this->filter = $method;
$this->filterValue = $value;
return $this;
}
public function getFilter()
{
return $this->filter;
}
public function getFilterValue()
{
return $this->filterValue;
}
public function setSort($method, $order = 'asc')
{
$order = strtoupper($order);
if (!in_array($order, array(\Criteria::ASC, \Criteria::DESC))) {
throw new \InvalidArgumentException(sprintf('"%s" is not a valid order: %s.', $order, implode(', ', array(\Criteria::ASC, \Criteria::DESC))));
}
$this->sort = $method;
$this->sortOrder = $order;
return $this;
}
public function getSort()
{
return $this->sort;
}
public function getSortOrder()
{
return $this->sortOrder;
}
public function setDisplayFieldAttrs($field, array $attr)
{
$this->displayFieldsAttrs[$field] = $attr;
return $this;
}
public function setDisplayFieldsAttrs(array $attrs)
{
foreach ($attrs as $key => $value) {
$this->setDisplayFieldAttrs($key, $value);
}
return $this;
}
public function getDisplayFieldsAttrs()
{
return $this->displayFieldsAttrs;
}
public function setDisplayFields(array $displayFields)
{
$this->displayFields = $displayFields;
return $this;
}
public function getDisplayFields()
{
return $this->displayFields;
}
public function setFilterDisplayFields(array $filterDisplayFields)
{
$this->filterDisplayFields = $filterDisplayFields;
return $this;
}
public function getFilterDisplayFields()
{
return $this->filterDisplayFields;
}
public function setFieldTemplate($field, $template)
{
$this->fieldsTemplates[$field] = $template;
return $this;
}
public function setFilterTemplate($field, $template)
{
$this->filtersTemplates[$field] = $template;
return $this;
}
public function setFieldHelper($field, $helper)
{
$this->fieldsHelpers[$field] = $helper;
return $this;
}
public function setRedirectIfOneResult($redirectIfOneResult)
{
$this->redirectIfOneResult = (bool) $redirectIfOneResult;
return $this;
}
public function getRedirectIfOneResult()
{
return $this->redirectIfOneResult;
}
public function setFilterMethod($field, $method, $criteria = null, $value = null)
{
$this->filtersMethods[$field] = array(
'method' => $method,
'criteria' => $criteria,
'value' => $value,
);
return $this;
}
public function getFiltersMethods()
{
return $this->filtersMethods;
}
public function getFieldsTemplates()
{
return $this->fieldsTemplates;
}
public function getFieldsHelpers()
{
return $this->fieldsHelpers;
}
public function setModel($model, $useDefaultNamespace = true)
{
if (!$useDefaultNamespace) {
$this->model = $model;
return $this;
}
if (!class_exists($this->modelNamespace.$model)) {
$this->modelNotFoundAdminException($this->modelNamespace.$model);
}
$this->model = $this->modelNamespace.$model;
return $this;
}
public function getModel()
{
return $this->model;
}
public function setModelPeer($modelPeer, $useDefaultNamespace = true)
{
if (!$useDefaultNamespace) {
$this->modelPeer = $modelPeer;
return $this;
}
if (!class_exists($this->modelNamespace.$modelPeer)) {
$this->modelNotFoundAdminException($this->modelNamespace.$modelPeer);
}
$this->modelPeer = $this->modelNamespace.$modelPeer;
return $this;
}
public function getModelPeer()
{
return $this->modelPeer;
}
public function setModelQuery($modelQuery, $useDefaultNamespace = true)
{
if (!$useDefaultNamespace) {
$this->modelQuery = $modelQuery;
return $this;
}
if (!class_exists($this->modelNamespace.$modelQuery)) {
$this->modelNotFoundAdminException($this->modelNamespace.$modelQuery);
}
$this->modelQuery = $this->modelNamespace.$modelQuery;
return $this;
}
public function getRoutePrefix()
{
if (null === $this->routePrefix) {
throw new \RuntimeException('You must set the route_prefix in the configuration of your admin bundle.');
}
return $this->routePrefix;
}
public function setRoutePrefix($routePrefix)
{
$this->routePrefix = $routePrefix;
return $this;
}
public function getModelQuery()
{
return $this->modelQuery;
}
public function setFormEdit($formEdit, $useDefaultNamespace = true)
{
if (!$useDefaultNamespace) {
$this->formEdit = $formEdit;
return $this;
}
if (!class_exists($this->getFormNamespace().$formEdit)) {
$this->modelNotFoundAdminException($this->getFormNamespace().$formEdit);
}
$this->formEdit = $this->getFormNamespace().$formEdit;
return $this;
}
public function getFormEdit()
{
return $this->formEdit;
}
public function setFormNew($formNew, $useDefaultNamespace = true)
{
if (!$useDefaultNamespace) {
$this->formNew = $formNew;
return $this;
}
if (!class_exists($this->getFormNamespace().$formNew)) {
$this->modelNotFoundAdminException($this->getFormNamespace().$formNew);
}
$this->formNew = $this->getFormNamespace().$formNew;
return $this;
}
public function getFormNew()
{
return $this->formNew;
}
public function setFormFilter($formFilter, $useDefaultNamespace = true)
{
if (!$useDefaultNamespace) {
$this->formFilter = $formFilter;
return $this;
}
if (!class_exists($this->getFilterNamespace().$formFilter)) {
$this->modelNotFoundAdminException($this->getFilterNamespace().$formFilter);
}
$this->formFilter = $this->getFilterNamespace().$formFilter;
return $this;
}
public function getFormFilter()
{
return $this->formFilter;
}
public function setEditTitle($editTitle)
{
$this->editTitle = $editTitle;
return $this;
}
public function setListTitle($listTitle)
{
$this->listTitle = $listTitle;
return $this;
}
public function setNewTitle($newTitle)
{
$this->newTitle = $newTitle;
return $this;
}
public function getEditTitle($object)
{
return $this->editTitle;
}
public function getListTitle()
{
return $this->listTitle;
}
public function getNewTitle()
{
return $this->newTitle;
}
public function setFormEditOptions($formEditOptions)
{
$this->formEditOptions = $formEditOptions;
return $this;
}
public function getFormEditOptions()
{
return $this->formEditOptions;
}
public function setFormNewOptions($formNewOptions)
{
$this->formNewOptions = $formNewOptions;
return $this;
}
public function getFormNewOptions()
{
return $this->formNewOptions;
}
public function setFormFilterOptions($formFilterOptions)
{
$this->formFilterOptions = $formFilterOptions;
return $this;
}
public function getFormFilterOptions()
{
return $this->formFilterOptions;
}
public function getCopyBatchAction()
{
return $this->copyBatchAction;
}
public function getDefaultFieldTemplate()
{
return 'TrinityAdminBundle:BaseAdmin:default.html.twig';
}
public function modelNotFoundAdminException($model)
{
throw new BaseAdminException\ModelNotFoundAdminException(sprintf('Model "%s" is not found.', $model));
}
public function setStorageNamespace($storageNamespace)
{
$this->storageNamespace = $storageNamespace;
return $this;
}
public function getStorageNamespace()
{
return $this->storageNamespace;
}
public function setRankable($bool)
{
$this->rankable = (bool) $bool;
return $this;
}
public function getRankable()
{
return $this->rankable;
}
public function setI18n($i18n, array $cultures)
{
$this->i18n = (bool) $i18n;
$this->i18nCultures = $cultures;
return $this;
}
public function setI18nCultures(array $cultures)
{
$this->i18nCultures = $cultures;
return $this;
}
public function getI18n()
{
return $this->i18n;
}
public function getI18nCultures()
{
return $this->i18nCultures;
}
public function setCollections(array $collections)
{
$this->collections = $collections;
return $this;
}
public function getCollections()
{
return $this->collections;
}
}

View file

@ -0,0 +1,876 @@
<?php
namespace Trinity\Bundle\AdminBundle\Controller;
use \BasePeer;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\File\File;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Pagerfanta\Adapter\PropelAdapter;
use Pagerfanta\Pagerfanta;
use Pagerfanta\Exception\NotValidCurrentPageException;
use Trinity\Bundle\AdminBundle\Exception\FilterMethodNotFoundException;
use Trinity\Bundle\AdminBundle\Form\Type\BatchType;
use Trinity\Bundle\AdminBundle\Form\Type\RankType;
use Trinity\Bundle\UserBundle\Flash\FlashError;
use Trinity\Bundle\UserBundle\Flash\FlashSuccess;
use Trinity\Bundle\UserBundle\Flash\FlashWarning;
use Trinity\Bundle\AdminBundle\Exception\RequestAdminException;
use Trinity\Component\Utils\Propel;
/**
* @Route("/admin")
*/
class BaseAdminController extends Controller
{
const UPLOAD_INTERFACE = 'Trinity\Component\File\FileUploadInterface';
const HISTORY_LIMIT = 10;
protected $configuration;
public function flashAction()
{
$user = $this->getSessionUser();
if (!$user->hasFlash('message', $this->getConfiguration()->getStorageNamespace())) {
return new Response();
}
$flash = $user->getFlash(
'message',
$this->getConfiguration()->getStorageNamespace()
);
return $this->render(
$flash->getTemplate(),
array(
'message' => $flash->getMessage()
)
);
}
public function filtersAction($routePrefix)
{
return $this->render(
'TrinityAdminBundle:BaseAdmin:filters.html.twig',
array(
'form_filter' => $this->getFormFilter()->createView(),
'filter_display_fields' => $this->getConfiguration()->getFilterDisplayFields(),
'filters_templates' => $this->getConfiguration()->getFiltersTemplates(),
'user_has_filter' => $this->getSessionUser()->getAttribute('filter', false, $this->getConfiguration()->getStorageNamespace()),
'route_prefix' => $routePrefix,
)
);
}
public function historyAction($routePrefix)
{
$query = $this->getQuery();
try {
$query->orderByUpdatedAt(\Criteria::DESC);
} catch (\PropelException $e) {
}
$query->limit(self::HISTORY_LIMIT);
return $this->render(
'TrinityAdminBundle:BaseAdmin:history.html.twig',
array(
'objects' => $query->find(),
'route_prefix' => $routePrefix,
)
);
}
protected function getQuery()
{
$modelQuery = $this->getConfiguration()->getModelQuery();
return $modelQuery::create();
}
protected function addSortToQuery(&$query)
{
if (!$this->getConfiguration()->getSortOrder()) {
return false;
}
$method = $this->getConfiguration()->getSort();
$method = $this->getConfiguration()->getRankable() ? 'orderByRank' : $method;
if (!$method) {
return false;
}
try {
call_user_func(array($query, $method), $this->getConfiguration()->getSortOrder());
} catch (\PropelException $e) {
}
return true;
}
protected function getFilters(Request $request)
{
if ($request->isMethod('POST')) {
$datas = $request->request->get($this->getFormFilter(true)->getName());
} else {
$datas = $request->query->get($this->getFormFilter(true)->getName());
}
if (!empty($datas)) {
return $datas;
}
return $this->getSessionUser()->getAttribute(
'filter',
array(),
$this->getConfiguration()->getStorageNamespace()
);
}
protected function addFiltersToQuery(&$query, Request $request)
{
$form = $this->getFormFilter(true);
$datas = $this->getFilters($request);
if (!is_array($datas)) {
return false;
}
$datas = $this->cleanFilterArray($datas);
$filtersMethods = $this->getConfiguration()->getFiltersMethods();
foreach ($datas as $field => $value) {
$method = isset($filtersMethods[$field]) ? $filtersMethods[$field]['method'] : 'filterBy'.Propel::camelCase($field);
$criteria = isset($filtersMethods[$field]) ? $filtersMethods[$field]['criteria'] : (is_numeric($value) && intval($value) == $value ? null : 'like');
$params = isset($filtersMethods[$field]) ? $filtersMethods[$field]['params'] : array();
if (!method_exists($this->getConfiguration()->getModelQuery(), $method)) {
throw new FilterMethodNotFoundException(sprintf('Filter method "%s" does not exist in class "%s"', $method, $this->getConfiguration()->getModelQuery()));
}
if (strtolower($criteria) == 'like') {
$value = '%'.$value.'%';
$criteria = null;
}
if ($value !== 'bool.both' && $value !== '%bool.both%') {
$bools = array(
'bool.true' => true,
'bool.false' => false,
'%bool.true%' => true,
'%bool.false%' => false,
);
if (isset($bools[$value])) {
$value = $bools[$value];
}
try {
$this->get('logger')->info(sprintf('Filter by "%s" with "%s", criteria: %s', $method, var_export($value, true), $criteria ? $criteria : 'NULL'));
$callParams = array_merge($criteria !== null ? array($value, $criteria) : array($value), $params);
call_user_func_array(array($query, $method), $callParams);
} catch (\PropelException $e) {
}
} else {
unset($datas[$field]);
}
}
$filterMethod = $this->getConfiguration()->getFilter();
if ($filterMethod !== null) {
if (!method_exists($this->getConfiguration()->getModelQuery(), $filterMethod)) {
throw new FilterMethodNotFoundException(sprintf('Filter method "%s" does not exist in class "%s"', $filterMethod, $this->getConfiguration()->getModelQuery()));
}
$value = $this->getConfiguration()->getFilterValue();
if (!is_array($value)) {
$value = array($value);
}
$this->get('logger')->info(sprintf('Filter by "%s" with "%s"', $filterMethod, var_export($value, true)));
call_user_func_array(array($query, $filterMethod), $value);
}
$this->getSessionUser()->setAttribute('filter', $datas, $this->getConfiguration()->getStorageNamespace());
$form->bind($datas);
return $form;
}
protected function getPager(Request $request)
{
$query = $this->getQuery();
$query->distinct();
$this->addSortToQuery($query);
$this->addFiltersToQuery($query, $request);
$adapter = new PropelAdapter($query);
$pagerfanta = new Pagerfanta($adapter);
$pagerfanta->setMaxPerPage($this->getConfiguration()->getMaxPerPage());
try {
$pagerfanta->setCurrentPage($this->getConfiguration()->getCurrentPage(), false, true);
} catch (NotValidCurrentPageException $e) {
$pagerfanta->setCurrentPage(1, false, true);
}
return $pagerfanta;
}
protected function getFields()
{
$modelPeer = $this->getConfiguration()->getModelPeer();
$peerFields = $modelPeer::getFieldNames(BasePeer::TYPE_FIELDNAME);
$peerFieldsCb = $modelPeer::getFieldNames();
$fields = array();
$finalFields = array();
$displayFields = $this->getConfiguration()->getDisplayFields();
$fieldsTemplates = $this->getConfiguration()->getFieldsTemplates();
if (!empty($displayFields)) {
$arrayPushBefore = function (array $array, $data, $pos) {
return array_merge(array_slice($array, 0, $pos), array($data), array_slice($array, $pos));
};
foreach ($displayFields as $k => $displayField) {
if (!in_array($displayField, $peerFields)) {
$method = ucfirst($displayField);
$peerFields = $arrayPushBefore($peerFields, $displayField, $k);
$peerFieldsCb = $arrayPushBefore($peerFieldsCb, $method, $k);
}
}
}
$fieldNames = new \ArrayIterator($peerFields);
$fieldNamesCb = new \ArrayIterator($peerFieldsCb);
while ($fieldNames->valid()) {
if (empty($displayFields) || (!empty($displayFields) && in_array($fieldNames->current(), $displayFields))) {
$method1 = Propel::getGetter($fieldNamesCb->current());
$method2 = lcfirst(preg_replace('/^get/', '', $method1));
$data = array(
'name' => $fieldNames->current(),
'method' => method_exists($this->getConfiguration()->getModel(), $method2) ? $method2 : $method1,
'template' => isset($fieldsTemplates[$fieldNames->current()]) ? $fieldsTemplates[$fieldNames->current()] : $this->getConfiguration()->getDefaultFieldTemplate()
);
if (empty($displayFields)) {
$fields[] = $data;
} else {
$keys = array_keys($displayFields, $fieldNames->current());
$fields[$keys[0]] = $data;
}
}
$fieldNames->next();
$fieldNamesCb->next();
}
$k = 0;
while (count($finalFields) !== count($fields)) {
if (isset($fields[$k])) {
$finalFields[] = $fields[$k];
}
$k++;
}
return $finalFields;
}
protected function redirectByRequest(Request $request, $object)
{
$list = array(
'edit_same' => $this->generateUrl(sprintf('%s_edit', $this->getConfiguration()->getRoutePrefix()), array('id' => $object->getId())),
'save_new' => $this->generateUrl(sprintf('%s_new', $this->getConfiguration()->getRoutePrefix())),
);
foreach ($list as $index => $uri) {
if ($request->request->has($index)) {
return $uri;
}
}
throw new RequestAdminException('No valid target (post submit) has been found.');
}
protected function getBatchType()
{
return $this->createForm(new BatchType());
}
protected function getRankType()
{
return $this->createForm(new RankType());
}
protected function processForm(&$form, &$object, Request $request)
{
$form->bind($request);
if ($form->isValid()) {
if ($object instanceof \FOS\UserBundle\Propel\User) {
if ($object->isNew()) {
$newUser = true;
} else {
$updatedUser = true;
}
}
$this->preSave($object);
$object->save();
$this->postSave($object);
if (!empty($newUser)) {
$this->get('trinity.user_log')->created($object, $this->getUser());
}
if (!empty($updatedUser)) {
$this->get('trinity.user_log')->updated($object, $this->getUser());
}
return $this->redirect($this->redirectByRequest($request, $object));
}
return false;
}
protected function removeObjects($query, array $pks)
{
foreach ($pks as $pk) {
$object = $query->findPK($pk);
$this->preRemove($object);
$object->delete();
$this->postRemove($object);
}
}
protected function copyObjects($query, array $pks)
{
foreach ($pks as $pk) {
$copy = $query->findPK($pk)->copy(true);
$this->preSave($copy);
$copy->save();
$this->postSave($copy);
}
}
protected function processBatchForm(&$form, Request $request)
{
$form->submit($request);
//if ($form->isValid()) {
$values = $request->request->get($form->getName());
if (!empty($values['objects'])) {
$modelQuery = $this->getConfiguration()->getModelQuery();
$query = new $modelQuery();
switch ($values['action']) {
case BatchType::BATCH_COPY: $this->copyObjects($query, $values['objects']); break;
case BatchType::BATCH_REMOVE: $this->removeObjects($query, $values['objects']); break;
}
$this->get('logger')->info(sprintf('Batch action (%s)', $values['action']));
return 2;
}
return 1;
//}
return 0;
}
protected function batchAction(Request $request)
{
$form = $this->getBatchType();
$redirect = $this->redirect(
$this->getSessionUser()->getAttribute(
'referer',
$this->generateUrl(sprintf('%s_index', $this->getConfiguration()->getRoutePrefix()), array('page' => 1))
)
);
$proccess = $this->processBatchForm($form, $request);
$namespace = $this->getConfiguration()->getStorageNamespace();
switch ($proccess) {
case 1: $this->getSessionUser()->setFlash('message', new FlashWarning('crud.flash.notselected'), false, $namespace); break;
case 2: $this->getSessionUser()->setFlash('message', new FlashSuccess('crud.flash.updated.plural'), false, $namespace); break;
}
return $redirect;
}
/**
* @Route("/", name="TrinityAdminBundle_index")
*/
public function indexAction($page, Request $request)
{
$this->getSessionUser()->setAttribute('referer', $request->getRequestUri());
$namespace = $this->getConfiguration()->getStorageNamespace();
$sortCookieName = $namespace.'_sort';
$pageCookieName = $namespace.'_page';
$sort = '';
if ($request->query->get('sort')) {
$sort = $request->query->get('sort');
} elseif ($sortCookie = $request->cookies->get($sortCookieName)) {
$sort = $sortCookie;
}
if (!$request->query->has('sort') && intval($page) === 1) {
if ($pageCookie = $request->cookies->get($pageCookieName)) {
$page = max(1, intval($pageCookie));
}
}
if ($format = $request->query->get('format')) {
if ($this->isValidExportFormat($format)) {
return $this->exportTo($format);
}
}
$this->getConfiguration()->setCurrentPage($page);
$this->addCookie(new Cookie($pageCookieName, $page, time() + 3600));
if (!empty($sort)) {
$parts = explode(':', $sort);
if (count($parts) == 2) {
list($field, $order) = $parts;
$method = 'orderBy'.Propel::camelCase($field);
$this->getConfiguration()->setSort($method, $order);
$this->get('logger')->info(sprintf('Order by "%s", "%s"', $method, $order));
$this->addCookie(new Cookie($sortCookieName, $sort, time() + 3600 * 24 * 360));
}
}
$pager = $this->getPager($request);
if ($this->getConfiguration()->getRedirectIfOneResult()) {
if ($this->getFilters($request) && count($pager) === 1 && $this->getConfiguration()->getIndexListAction('edit')) {
$this->getSessionUser()->setAttribute('filter', null, $this->getConfiguration()->getStorageNamespace());
return $this->redirect($this->generateUrl(sprintf('%s_edit',$this->getConfiguration()->getRoutePrefix()), array('id' => $pager->getIterator()->offsetGet(0)->getId())));
}
}
return array(
'pager' => $pager,
'fields' => $this->getFields(),
'fields_templates' => $this->getConfiguration()->getFieldsTemplates(),
'fields_attrs' => $this->getConfiguration()->getDisplayFieldsAttrs(),
'list_actions' => $this->getConfiguration()->getIndexListActions(),
'index_actions' => $this->getConfiguration()->getIndexActions(),
'batch_actions' => $this->getConfiguration()->getBatchActions(),
'context_menu' => $this->getConfiguration()->getContextMenu(),
'export' => $this->getConfiguration()->getExport(),
'exportFormats' => $this->getConfiguration()->getExportFormats(),
'rankable' => $this->getConfiguration()->getRankable(),
'remove_token' => $this->getRemoveToken(true),
'fieldsnames' => $this->getConfiguration()->getFieldsnames(),
'templating' => $this->container->get('templating'),
'form_batch' => $this->getBatchType()->createView(),
'form_rank' => $this->getRankType()->createView(),
'title' => $this->getConfiguration()->getListTitle(),
'i18n' => $this->getConfiguration()->getI18n(),
'i18n_cultures' => $this->getConfiguration()->getI18nCultures(),
'pager_sort' => $sort,
);
}
protected function addCookie(Cookie $cookie)
{
$response = new Response();
$response->headers->setCookie($cookie);
return $response->send();
}
protected function exportTo($format)
{
$query = $this->getQuery();
$this->addSortToQuery($query);
$this->addFiltersToQuery($query, $this->getRequest());
$render = $this->render(
'TrinityAdminBundle:BaseAdmin:export.html.twig',
array(
'datas' => $query->find()->exportTo($format),
)
);
$render->headers->set('Content-Type', $this->getExportContentTypeByFormat($format));
$render->headers->set('Content-disposition', sprintf('filename="export-%s%s"', time(), $this->getExportExtensionByFormat($format)));
return $render;
}
public function clearFilterAction(Request $request)
{
$redirect = $this->redirect(
$this->getSessionUser()->getAttribute(
'referer',
$this->generateUrl(sprintf('%s_index', $this->getConfiguration()->getRoutePrefix()), array('page' => 1))
)
);
$this->getSessionUser()->setAttribute('filter', null, $this->getConfiguration()->getStorageNamespace());
return $redirect;
}
public function editAction($object, Request $request)
{
if (!$object) {
$this->getSessionUser()->setFlash('message', new FlashWarning('crud.flash.unknown'), false, $this->getConfiguration()->getStorageNamespace());
return $this->redirect($this->generateUrl(sprintf('%s_index',$this->getConfiguration()->getRoutePrefix())));
}
$form = $this->getConfiguration()->getFormEdit();
if($this->has($form)){
$form = $this->createForm($this->get($form)->getName(), $object, $this->getConfiguration()->getFormEditOptions());
}else {
$form = $this->createForm(new $form($this->getConfiguration()->getFormEditOptions()), $object);
}
if ('POST' === $request->getMethod()) {
if (false !== $processForm = $this->processForm($form, $object, $request)) {
$this->getSessionUser()->setFlash('message', new FlashSuccess('crud.flash.updated.singular'), false, $this->getConfiguration()->getStorageNamespace());
return $processForm;
}
$this->getSessionUser()->setFlash('message', new FlashError('crud.flash.fail.update'), false, $this->getConfiguration()->getStorageNamespace());
}
return array(
'object' => $object,
'created_at' => (method_exists($object, 'getCreatedAt'))?$object->getCreatedAt('d/m/Y'):null,
'updated_at' => (method_exists($object, 'getUpdatedAt'))?$object->getUpdatedAt('d/m/Y'):null,
'form' => $form->createView(),
'fieldsets' => $this->getConfiguration()->getFieldsets(),
'fieldsetsView' => $this->getConfiguration()->getFieldsetsView(),
'fieldsnames' => $this->getConfiguration()->getFieldsnames(),
'fields_helpers' => $this->getConfiguration()->getFieldsHelpers(),
'remove_token' => $this->getRemoveToken(true),
'title' => $this->getConfiguration()->getEditTitle($object),
'i18n' => $this->getConfiguration()->getI18n(),
'i18n_cultures' => $this->getConfiguration()->getI18nCultures(),
'collections' => $this->getConfiguration()->getCollections(),
);
}
public function newAction(Request $request)
{
$model = $this->getConfiguration()->getModel();
$object = new $model();
$form = $this->getConfiguration()->getFormNew();
if($this->has($form)){
$form = $this->createForm($this->get($form)->getName(), $object, $this->getConfiguration()->getFormNewOptions());
}else {
$form = $this->createForm(new $form($this->getConfiguration()->getFormNewOptions()), $object);
}
if ('POST' === $request->getMethod()) {
if (false !== $processForm = $this->processForm($form, $object, $request)) {
$this->getSessionUser()->setFlash('message', new FlashSuccess('crud.flash.updated.singular'), false, $this->getConfiguration()->getStorageNamespace());
return $processForm;
}
$this->getSessionUser()->setFlash('message', new FlashError('crud.flash.fail.new'), false, $this->getConfiguration()->getStorageNamespace());
}
return array(
'form' => $form->createView(),
'fieldsets' => $this->getConfiguration()->getFieldsets(),
'fieldsetsView' => $this->getConfiguration()->getFieldsetsView(),
'fieldsnames' => $this->getConfiguration()->getFieldsnames(),
'fields_helpers' => $this->getConfiguration()->getFieldsHelpers(),
'title' => $this->getConfiguration()->getNewTitle(),
'i18n' => $this->getConfiguration()->getI18n(),
'i18n_cultures' => $this->getConfiguration()->getI18nCultures(),
'collections' => $this->getConfiguration()->getCollections(),
);
}
public function removeAction($object, $token, Request $request)
{
if ($object) {
if ($this->getRemoveToken() !== $token) {
$this->getSessionUser()->setFlash('message', new FlashError('crud.flash.token'), false, $this->getConfiguration()->getStorageNamespace());
} else {
try {
$this->preRemove($object);
$object->delete();
$this->postRemove($object);
$this->getSessionUser()->setFlash('message', new FlashSuccess('crud.flash.removed'), false, $this->getConfiguration()->getStorageNamespace());
} catch (PropelException $e) {
$this->getSessionUser()->setFlash('message', new FlashError('crud.flash.fail.remove'), false, $this->getConfiguration()->getStorageNamespace());
}
}
} else {
$this->getSessionUser()->setFlash('message', new FlashWarning('crud.flash.unknown'), false, $this->getConfiguration()->getStorageNamespace());
}
return $this->redirect($this->generateUrl(sprintf('%s_index',$this->getConfiguration()->getRoutePrefix())));
}
public function rankAction(Request $request)
{
$form = $this->getRankType();
$form->bind($request);
if ($form->isValid()) {
$datas = $form->getData();
$ids = explode(' ', $datas['objects']);
$page = $datas['page'];
$query = $this->getQuery();
foreach ($ids as $k => $id) {
$rank = ($this->getConfiguration()->getMaxPerPage() * $page) + $k + 1;
$object = $query->findOneById($id);
if ($object) {
$object->setRank($rank)->save();
}
}
}
return null;
}
protected function getRemoveToken($getNew = false)
{
$attributeName = 'remove_token_'.$this->getConfiguration()->getModel();
if ($getNew) {
$token = sha1(uniqid().time());
$this->getSessionUser()->setAttribute($attributeName, $token);
return $token;
}
return $this->getSessionUser()->getAttribute($attributeName);
}
protected function isValidExportFormat($format)
{
return in_array($format, array('XML', 'CSV', 'JSON', 'YAML'));
}
protected function getExportContentTypeByFormat($format)
{
if (!$this->isValidExportFormat($format)) {
return null;
}
$formats = array(
'XML' => 'text/xml',
'CSV' => 'text/csv',
'JSON' => 'text/json',
'YAML' => 'text/yaml',
);
return $formats[$format];
}
protected function getExportExtensionByFormat($format)
{
if (!$this->isValidExportFormat($format)) {
return null;
}
$formats = array(
'XML' => '.xml',
'CSV' => '.csv',
'JSON' => '.json',
'YAML' => '.yml',
);
return $formats[$format];
}
protected function getFormFilter($new = false)
{
$form = $this->getConfiguration()->getFormFilter() ? $this->getConfiguration()->getFormFilter() : $this->getConfiguration()->getFormNew();
$form = $this->createForm(new $form($this->getConfiguration()->getFormFilterOptions()));
if (!$new) {
$datas = $this->cleanFilterArray($this->getSessionUser()->getAttribute('filter', array(), $this->getConfiguration()->getStorageNamespace()));
$form->bind($datas);
}
return $form;
}
protected function cleanFilterArray(array $array)
{
foreach ($array as $k => $v) {
if (trim($v) === '') {
unset($array[$k]);
}
}
return $array;
}
/**
* @return mixed
* @throws \LogicException
*/
public function getConfiguration()
{
if (empty($this->configuration)) {
throw new \LogicException('You must specify a crud configuration.');
}
if (null === $this->configuration->getStorageNamespace()) {
$this->configuration->setStorageNamespace(get_class($this));
}
return $this->configuration;
}
/**
* @Route("/jsTranslations.js", name="TrinityAdminBundle_jsTranslation")
* @Template("TrinityAdminBundle:BaseAdmin:jsTranslation.html.twig")
*/
public function jsTranslationAction(Request $request)
{
}
public function getUser()
{
if (!$this->container->has('security.context')) {
throw new \LogicException('The SecurityBundle is not registered in your application.');
}
if (null === $token = $this->container->get('security.context')->getToken()) {
return null;
}
if (!is_object($user = $token->getUser())) {
return null;
}
if (method_exists($user, 'setStorage')) {
$user->setStorage($this->container->get('trinity.storage'));
}
return $user;
}
public function getSessionUser()
{
return $this->container->get('trinity.session_user');
}
public function preSave($object)
{
}
public function postSave($object, $wasNew = false)
{
}
public function preRemove($object)
{
}
public function postRemove($object)
{
}
public function postDelete($object)
{
return $this->postRemove($object);
}
public function preDelete($object)
{
return $this->preRemove($object);
}
public function cleanString($text)
{
$text = preg_replace('`</?[^>]+>`U', '', $text);
$encoding = mb_detect_encoding($text);
$text = str_replace(array('&nbsp;', '&rsquo;'), ' ',$text);
$text = html_entity_decode(strip_tags($text));
if ($encoding!='UTF-8') $text = utf8_encode($text);
$text = str_replace(
array(
'à', 'â', 'ä', 'á', 'ã', 'å',
'î', 'ï', 'ì', 'í',
'ô', 'ö', 'ò', 'ó', 'õ', 'ø',
'ù', 'û', 'ü', 'ú',
'é', 'è', 'ê', 'ë',
'ç', 'ÿ', 'ñ',
'À', 'Â', 'Ä', 'Á', 'Ã', 'Å',
'Î', 'Ï', 'Ì', 'Í',
'Ô', 'Ö', 'Ò', 'Ó', 'Õ', 'Ø',
'Ù', 'Û', 'Ü', 'Ú',
'É', 'È', 'Ê', 'Ë',
'Ç', 'Ÿ', 'Ñ',
'\'', '"',
' ', ' ', ' ', ' ', ' '
),
array(
'a', 'a', 'a', 'a', 'a', 'a',
'i', 'i', 'i', 'i',
'o', 'o', 'o', 'o', 'o', 'o',
'u', 'u', 'u', 'u',
'e', 'e', 'e', 'e',
'c', 'y', 'n',
'A', 'A', 'A', 'A', 'A', 'A',
'I', 'I', 'I', 'I',
'O', 'O', 'O', 'O', 'O', 'O',
'U', 'U', 'U', 'U',
'E', 'E', 'E', 'E',
'C', 'Y', 'N',
' ', ' ',
' ', ' ', ' ', ' ', ' '
),$text);
return strtolower($text);
}
}

View file

@ -0,0 +1,47 @@
<?php
namespace Trinity\Bundle\AdminBundle\DependencyInjection;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
/**
* This is the class that validates and merges configuration from your app/config files
*
* To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html#cookbook-bundles-extension-config-class}
*/
class Configuration implements ConfigurationInterface
{
/**
* {@inheritDoc}
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('trinity_admin');
/*$rootNode
->children()
->arrayNode('i18n')
->info('I18n configuration')
->children()
->booleanNode('active')
->defaultFalse()
->end()
->arrayNode('langs')
->info('Langs configuration')
->requiresAtLeastOneElement()
->prototype('array')->end()
->end()
->end()
->end()
->end()
;*/
// Here you should define the parameters that are allowed to
// configure your bundle. See the documentation linked above for
// more information on that topic.
return $treeBuilder;
}
}

View file

@ -0,0 +1,29 @@
<?php
namespace Trinity\Bundle\AdminBundle\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\DependencyInjection\Definition;
/**
* This is the class that loads and manages your bundle configuration
*
* To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html}
*/
class TrinityAdminExtension extends Extension
{
/**
* {@inheritDoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.xml');
}
}

View file

@ -0,0 +1,7 @@
<?php
namespace Trinity\Bundle\AdminBundle\Exception;
class FilterMethodNotFoundException extends \Exception
{
}

View file

@ -0,0 +1,7 @@
<?php
namespace Trinity\Bundle\AdminBundle\Exception;
class ModelNotFoundAdminException extends \Exception
{
}

View file

@ -0,0 +1,7 @@
<?php
namespace Trinity\Bundle\AdminBundle\Exception;
class RequestAdminException extends \Exception
{
}

View file

@ -0,0 +1,40 @@
<?php
namespace Trinity\Component\File;
use Symfony\Component\HttpFoundation\File\File;
use Trinity\Component\Exception\FileMethodNotFoundException;
class FileUploadCallback
{
protected $object;
protected $name;
public function __construct(FileUploadInterface $object, $name)
{
$this->object = $object;
$this->name = $name;
}
public function removeFile()
{
$getter = sprintf('get%s', ucfirst($this->name));
$setter = sprintf('set%s', ucfirst($this->name));
$file = call_user_func(array($this->object, $getter));
if (null !== $file && is_object($file) && $file instanceof File) {
return unlink($file->getRealpath());
}
return call_user_func(array($this->object, $setter), '');
}
public function rollBackField()
{
$rollback = sprintf('rollback_%s', $this->name);
$setter = sprintf('set%s', ucfirst($this->name));
return call_user_func(array($this->object, $setter), $this->object->$rollback);
}
}

View file

@ -0,0 +1,8 @@
<?php
namespace Trinity\Bundle\AdminBundle\File;
interface FileUploadInterface
{
public function getFilesFields();
}

View file

@ -0,0 +1,60 @@
<?php
namespace Trinity\Bundle\AdminBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class BatchType extends AbstractType
{
const BATCH_COPY = 'copy';
const BATCH_REMOVE = 'remove';
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add(
'objects',
'choice',
array(
'required' => true,
'multiple' => true,
'expanded' => true,
)
);
$builder->add(
'action',
'choice',
array(
'required' => true,
'choices' => array(
self::BATCH_COPY => 'Copy',
self::BATCH_REMOVE => 'Remove',
),
'multiple' => false,
)
);
}
/**
* {@inheritdoc}
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
));
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'batch';
}
}

View file

@ -0,0 +1,32 @@
<?php
namespace Trinity\Bundle\AdminBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class FilterBooleanType extends AbstractType
{
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'required' => false,
'empty_value' => false,
'choices' => array(
'bool.both' => 'Anyway',
'bool.true' => 'True',
'bool.false' => 'False',
)
));
}
public function getParent()
{
return 'choice';
}
public function getName()
{
return 'filter_boolean';
}
}

View file

@ -0,0 +1,50 @@
<?php
namespace Trinity\Bundle\AdminBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class RankType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add(
'objects',
'hidden',
array(
'required' => false,
)
);
$builder->add(
'page',
'hidden',
array(
'required' => false,
)
);
}
/**
* {@inheritdoc}
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
));
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'rank';
}
}

View file

@ -0,0 +1,21 @@
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="field.twig.extension.class">Trinity\Bundle\AdminBundle\Twig\Extension\FieldExtension</parameter>
</parameters>
<services>
<service id="field.twig.extension" class="%field.twig.extension.class%" public="true">
<tag name="twig.extension" />
</service>
<service id="form.type.filter_boolean" class="Trinity\Bundle\AdminBundle\Form\Type\FilterBooleanType">
<tag name="form.type" alias="filter_boolean" />
</service>
</services>
</container>

Binary file not shown.

After

Width:  |  Height:  |  Size: 646 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 872 B

View file

@ -0,0 +1,430 @@
/* @group Base */
.chosen-container {
position: relative;
display: inline-block;
vertical-align: middle;
font-size: 13px;
zoom: 1;
*display: inline;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
.chosen-container .chosen-drop {
position: absolute;
top: 100%;
left: -9999px;
z-index: 1010;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
width: 100%;
border: 1px solid #aaa;
border-top: 0;
background: #fff;
box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15);
}
.chosen-container.chosen-with-drop .chosen-drop {
left: 0;
}
.chosen-container a {
cursor: pointer;
}
/* @end */
/* @group Single Chosen */
.chosen-container-single .chosen-single {
position: relative;
display: block;
overflow: hidden;
padding: 0 0 0 8px;
height: 23px;
border: 1px solid #aaa;
border-radius: 5px;
background-color: #fff;
background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #ffffff), color-stop(50%, #f6f6f6), color-stop(52%, #eeeeee), color-stop(100%, #f4f4f4));
background: -webkit-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
background: -moz-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
background: -o-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
background: linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
background-clip: padding-box;
box-shadow: 0 0 3px white inset, 0 1px 1px rgba(0, 0, 0, 0.1);
color: #444;
text-decoration: none;
white-space: nowrap;
line-height: 24px;
}
.chosen-container-single .chosen-default {
color: #999;
}
.chosen-container-single .chosen-single span {
display: block;
overflow: hidden;
margin-right: 26px;
text-overflow: ellipsis;
white-space: nowrap;
}
.chosen-container-single .chosen-single-with-deselect span {
margin-right: 38px;
}
.chosen-container-single .chosen-single abbr {
position: absolute;
top: 6px;
right: 26px;
display: block;
width: 12px;
height: 12px;
background: url('chosen-sprite.png') -42px 1px no-repeat;
font-size: 1px;
}
.chosen-container-single .chosen-single abbr:hover {
background-position: -42px -10px;
}
.chosen-container-single.chosen-disabled .chosen-single abbr:hover {
background-position: -42px -10px;
}
.chosen-container-single .chosen-single div {
position: absolute;
top: 0;
right: 0;
display: block;
width: 18px;
height: 100%;
}
.chosen-container-single .chosen-single div b {
display: block;
width: 100%;
height: 100%;
background: url('chosen-sprite.png') no-repeat 0px 2px;
}
.chosen-container-single .chosen-search {
position: relative;
z-index: 1010;
margin: 0;
padding: 3px 4px;
white-space: nowrap;
}
.chosen-container-single .chosen-search input[type="text"] {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
margin: 1px 0;
padding: 4px 20px 4px 5px;
width: 100%;
height: auto;
outline: 0;
border: 1px solid #aaa;
background: white url('chosen-sprite.png') no-repeat 100% -20px;
background: url('chosen-sprite.png') no-repeat 100% -20px, -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
background: url('chosen-sprite.png') no-repeat 100% -20px, -webkit-linear-gradient(#eeeeee 1%, #ffffff 15%);
background: url('chosen-sprite.png') no-repeat 100% -20px, -moz-linear-gradient(#eeeeee 1%, #ffffff 15%);
background: url('chosen-sprite.png') no-repeat 100% -20px, -o-linear-gradient(#eeeeee 1%, #ffffff 15%);
background: url('chosen-sprite.png') no-repeat 100% -20px, linear-gradient(#eeeeee 1%, #ffffff 15%);
font-size: 1em;
font-family: sans-serif;
line-height: normal;
border-radius: 0;
}
.chosen-container-single .chosen-drop {
margin-top: -10px;
border-radius: 0 0 4px 4px;
background-clip: padding-box;
}
.chosen-container-single.chosen-container-single-nosearch .chosen-search {
position: absolute;
left: -9999px;
}
/* @end */
/* @group Results */
.chosen-container .chosen-results {
position: relative;
overflow-x: hidden;
overflow-y: auto;
margin: 0 4px 4px 0;
padding: 0 0 0 4px;
max-height: 240px;
-webkit-overflow-scrolling: touch;
}
.chosen-container .chosen-results li {
display: none;
margin: 0;
padding: 5px 6px;
list-style: none;
line-height: 15px;
}
.chosen-container .chosen-results li.active-result {
display: list-item;
cursor: pointer;
}
.chosen-container .chosen-results li.disabled-result {
display: list-item;
color: #ccc;
cursor: default;
}
.chosen-container .chosen-results li.highlighted {
background-color: #3875d7;
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #3875d7), color-stop(90%, #2a62bc));
background-image: -webkit-linear-gradient(#3875d7 20%, #2a62bc 90%);
background-image: -moz-linear-gradient(#3875d7 20%, #2a62bc 90%);
background-image: -o-linear-gradient(#3875d7 20%, #2a62bc 90%);
background-image: linear-gradient(#3875d7 20%, #2a62bc 90%);
color: #fff;
}
.chosen-container .chosen-results li.no-results {
display: list-item;
background: #f4f4f4;
}
.chosen-container .chosen-results li.group-result {
display: list-item;
font-weight: bold;
cursor: default;
}
.chosen-container .chosen-results li.group-option {
padding-left: 15px;
}
.chosen-container .chosen-results li em {
font-style: normal;
text-decoration: underline;
}
/* @end */
/* @group Multi Chosen */
.chosen-container-multi .chosen-choices {
position: relative;
overflow: hidden;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
margin: 0;
padding: 0;
width: 100%;
height: auto !important;
height: 1%;
border: 1px solid #aaa;
background-color: #fff;
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
background-image: -webkit-linear-gradient(#eeeeee 1%, #ffffff 15%);
background-image: -moz-linear-gradient(#eeeeee 1%, #ffffff 15%);
background-image: -o-linear-gradient(#eeeeee 1%, #ffffff 15%);
background-image: linear-gradient(#eeeeee 1%, #ffffff 15%);
cursor: text;
}
.chosen-container-multi .chosen-choices li {
float: left;
list-style: none;
}
.chosen-container-multi .chosen-choices li.search-field {
margin: 0;
padding: 0;
white-space: nowrap;
}
.chosen-container-multi .chosen-choices li.search-field input[type="text"] {
margin: 1px 0;
padding: 5px;
height: 15px;
outline: 0;
border: 0 !important;
background: transparent !important;
box-shadow: none;
color: #666;
font-size: 100%;
font-family: sans-serif;
line-height: normal;
border-radius: 0;
}
.chosen-container-multi .chosen-choices li.search-field .default {
color: #999;
}
.chosen-container-multi .chosen-choices li.search-choice {
position: relative;
margin: 3px 0 3px 5px;
padding: 3px 20px 3px 5px;
border: 1px solid #aaa;
border-radius: 3px;
background-color: #e4e4e4;
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
background-image: -webkit-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-image: -moz-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-image: -o-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-image: linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-clip: padding-box;
box-shadow: 0 0 2px white inset, 0 1px 0 rgba(0, 0, 0, 0.05);
color: #333;
line-height: 13px;
cursor: default;
}
.chosen-container-multi .chosen-choices li.search-choice .search-choice-close {
position: absolute;
top: 4px;
right: 3px;
display: block;
width: 12px;
height: 12px;
background: url('chosen-sprite.png') -42px 1px no-repeat;
font-size: 1px;
}
.chosen-container-multi .chosen-choices li.search-choice .search-choice-close:hover {
background-position: -42px -10px;
}
.chosen-container-multi .chosen-choices li.search-choice-disabled {
padding-right: 5px;
border: 1px solid #ccc;
background-color: #e4e4e4;
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
color: #666;
}
.chosen-container-multi .chosen-choices li.search-choice-focus {
background: #d4d4d4;
}
.chosen-container-multi .chosen-choices li.search-choice-focus .search-choice-close {
background-position: -42px -10px;
}
.chosen-container-multi .chosen-results {
margin: 0;
padding: 0;
}
.chosen-container-multi .chosen-drop .result-selected {
display: list-item;
color: #ccc;
cursor: default;
}
/* @end */
/* @group Active */
.chosen-container-active .chosen-single {
border: 1px solid #5897fb;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
}
.chosen-container-active.chosen-with-drop .chosen-single {
border: 1px solid #aaa;
-moz-border-radius-bottomright: 0;
border-bottom-right-radius: 0;
-moz-border-radius-bottomleft: 0;
border-bottom-left-radius: 0;
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #eeeeee), color-stop(80%, #ffffff));
background-image: -webkit-linear-gradient(#eeeeee 20%, #ffffff 80%);
background-image: -moz-linear-gradient(#eeeeee 20%, #ffffff 80%);
background-image: -o-linear-gradient(#eeeeee 20%, #ffffff 80%);
background-image: linear-gradient(#eeeeee 20%, #ffffff 80%);
box-shadow: 0 1px 0 #fff inset;
}
.chosen-container-active.chosen-with-drop .chosen-single div {
border-left: none;
background: transparent;
}
.chosen-container-active.chosen-with-drop .chosen-single div b {
background-position: -18px 2px;
}
.chosen-container-active .chosen-choices {
border: 1px solid #5897fb;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
}
.chosen-container-active .chosen-choices li.search-field input[type="text"] {
color: #111 !important;
}
/* @end */
/* @group Disabled Support */
.chosen-disabled {
opacity: 0.5 !important;
cursor: default;
}
.chosen-disabled .chosen-single {
cursor: default;
}
.chosen-disabled .chosen-choices .search-choice .search-choice-close {
cursor: default;
}
/* @end */
/* @group Right to Left */
.chosen-rtl {
text-align: right;
}
.chosen-rtl .chosen-single {
overflow: visible;
padding: 0 8px 0 0;
}
.chosen-rtl .chosen-single span {
margin-right: 0;
margin-left: 26px;
direction: rtl;
}
.chosen-rtl .chosen-single-with-deselect span {
margin-left: 38px;
}
.chosen-rtl .chosen-single div {
right: auto;
left: 3px;
}
.chosen-rtl .chosen-single abbr {
right: auto;
left: 26px;
}
.chosen-rtl .chosen-choices li {
float: right;
}
.chosen-rtl .chosen-choices li.search-field input[type="text"] {
direction: rtl;
}
.chosen-rtl .chosen-choices li.search-choice {
margin: 3px 5px 3px 0;
padding: 3px 5px 3px 19px;
}
.chosen-rtl .chosen-choices li.search-choice .search-choice-close {
right: auto;
left: 4px;
}
.chosen-rtl.chosen-container-single-nosearch .chosen-search,
.chosen-rtl .chosen-drop {
left: 9999px;
}
.chosen-rtl.chosen-container-single .chosen-results {
margin: 0 0 4px 4px;
padding: 0 4px 0 0;
}
.chosen-rtl .chosen-results li.group-option {
padding-right: 15px;
padding-left: 0;
}
.chosen-rtl.chosen-container-active.chosen-with-drop .chosen-single div {
border-right: none;
}
.chosen-rtl .chosen-search input[type="text"] {
padding: 4px 5px 4px 20px;
background: white url('chosen-sprite.png') no-repeat -30px -20px;
background: url('chosen-sprite.png') no-repeat -30px -20px, -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
background: url('chosen-sprite.png') no-repeat -30px -20px, -webkit-linear-gradient(#eeeeee 1%, #ffffff 15%);
background: url('chosen-sprite.png') no-repeat -30px -20px, -moz-linear-gradient(#eeeeee 1%, #ffffff 15%);
background: url('chosen-sprite.png') no-repeat -30px -20px, -o-linear-gradient(#eeeeee 1%, #ffffff 15%);
background: url('chosen-sprite.png') no-repeat -30px -20px, linear-gradient(#eeeeee 1%, #ffffff 15%);
direction: rtl;
}
.chosen-rtl.chosen-container-single .chosen-single div b {
background-position: 6px 2px;
}
.chosen-rtl.chosen-container-single.chosen-with-drop .chosen-single div b {
background-position: -12px 2px;
}
/* @end */
/* @group Retina compatibility */
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-resolution: 144dpi) {
.chosen-rtl .chosen-search input[type="text"],
.chosen-container-single .chosen-single abbr,
.chosen-container-single .chosen-single div b,
.chosen-container-single .chosen-search input[type="text"],
.chosen-container-multi .chosen-choices .search-choice .search-choice-close,
.chosen-container .chosen-results-scroll-down span,
.chosen-container .chosen-results-scroll-up span {
background-image: url('chosen-sprite@2x.png') !important;
background-size: 52px 37px !important;
background-repeat: no-repeat !important;
}
}
/* @end */

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

View file

@ -0,0 +1,108 @@
/**
* okaidia theme for JavaScript, CSS and HTML
* Loosely based on Monokai textmate theme by http://www.monokai.nl/
* @author ocodia
*/
code[class*="language-"],
pre[class*="language-"] {
color: #f8f8f2;
text-shadow: 0 1px rgba(0,0,0,0.3);
font-family: Consolas, Monaco, 'Andale Mono', monospace;
direction: ltr;
text-align: left;
white-space: pre;
word-spacing: normal;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
/* Code blocks */
pre[class*="language-"] {
padding: 1em;
margin: .5em 0;
overflow: auto;
border-radius: 0.3em;
}
:not(pre) > code[class*="language-"],
pre[class*="language-"] {
background: #272822;
}
/* Inline code */
:not(pre) > code[class*="language-"] {
padding: .1em;
border-radius: .3em;
}
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: slategray;
}
.token.punctuation {
color: #f8f8f2;
}
.namespace {
opacity: .7;
}
.token.property,
.token.tag {
color: #f92672;
}
.token.boolean,
.token.number{
color: #ae81ff;
}
.token.selector,
.token.attr-name,
.token.string {
color: #a6e22e;
}
.token.operator,
.token.entity,
.token.url,
.language-css .token.string,
.style .token.string {
color: #f8f8f2;
}
.token.atrule,
.token.attr-value
{
color: #e6db74;
}
.token.keyword{
color: #66d9ef;
}
.token.regex,
.token.important {
color: #fd971f;
}
.token.important {
font-weight: bold;
}
.token.entity {
cursor: help;
}

View file

@ -0,0 +1,9 @@
/**
* Prism: Lightweight, robust, elegant syntax highlighting
* MIT license http://www.opensource.org/licenses/mit-license.php/
* @author Lea Verou http://lea.verou.me
*/(function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=self.Prism={util:{type:function(e){return Object.prototype.toString.call(e).match(/\[object (\w+)\]/)[1]},clone:function(e){var n=t.util.type(e);switch(n){case"Object":var r={};for(var i in e)e.hasOwnProperty(i)&&(r[i]=t.util.clone(e[i]));return r;case"Array":return e.slice()}return e}},languages:{extend:function(e,n){var r=t.util.clone(t.languages[e]);for(var i in n)r[i]=n[i];return r},insertBefore:function(e,n,r,i){i=i||t.languages;var s=i[e],o={};for(var u in s)if(s.hasOwnProperty(u)){if(u==n)for(var a in r)r.hasOwnProperty(a)&&(o[a]=r[a]);o[u]=s[u]}return i[e]=o},DFS:function(e,n){for(var r in e){n.call(e,r,e[r]);t.util.type(e)==="Object"&&t.languages.DFS(e[r],n)}}},highlightAll:function(e,n){var r=document.querySelectorAll('code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code');for(var i=0,s;s=r[i++];)t.highlightElement(s,e===!0,n)},highlightElement:function(r,i,s){var o,u,a=r;while(a&&!e.test(a.className))a=a.parentNode;if(a){o=(a.className.match(e)||[,""])[1];u=t.languages[o]}if(!u)return;r.className=r.className.replace(e,"").replace(/\s+/g," ")+" language-"+o;a=r.parentNode;/pre/i.test(a.nodeName)&&(a.className=a.className.replace(e,"").replace(/\s+/g," ")+" language-"+o);var f=r.textContent;if(!f)return;f=f.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/\u00a0/g," ");var l={element:r,language:o,grammar:u,code:f};t.hooks.run("before-highlight",l);if(i&&self.Worker){var c=new Worker(t.filename);c.onmessage=function(e){l.highlightedCode=n.stringify(JSON.parse(e.data),o);t.hooks.run("before-insert",l);l.element.innerHTML=l.highlightedCode;s&&s.call(l.element);t.hooks.run("after-highlight",l)};c.postMessage(JSON.stringify({language:l.language,code:l.code}))}else{l.highlightedCode=t.highlight(l.code,l.grammar,l.language);t.hooks.run("before-insert",l);l.element.innerHTML=l.highlightedCode;s&&s.call(r);t.hooks.run("after-highlight",l)}},highlight:function(e,r,i){return n.stringify(t.tokenize(e,r),i)},tokenize:function(e,n,r){var i=t.Token,s=[e],o=n.rest;if(o){for(var u in o)n[u]=o[u];delete n.rest}e:for(var u in n){if(!n.hasOwnProperty(u)||!n[u])continue;var a=n[u],f=a.inside,l=!!a.lookbehind,c=0;a=a.pattern||a;for(var h=0;h<s.length;h++){var p=s[h];if(s.length>e.length)break e;if(p instanceof i)continue;a.lastIndex=0;var d=a.exec(p);if(d){l&&(c=d[1].length);var v=d.index-1+c,d=d[0].slice(c),m=d.length,g=v+m,y=p.slice(0,v+1),b=p.slice(g+1),w=[h,1];y&&w.push(y);var E=new i(u,f?t.tokenize(d,f):d);w.push(E);b&&w.push(b);Array.prototype.splice.apply(s,w)}}}return s},hooks:{all:{},add:function(e,n){var r=t.hooks.all;r[e]=r[e]||[];r[e].push(n)},run:function(e,n){var r=t.hooks.all[e];if(!r||!r.length)return;for(var i=0,s;s=r[i++];)s(n)}}},n=t.Token=function(e,t){this.type=e;this.content=t};n.stringify=function(e,r,i){if(typeof e=="string")return e;if(Object.prototype.toString.call(e)=="[object Array]")return e.map(function(t){return n.stringify(t,r,e)}).join("");var s={type:e.type,content:n.stringify(e.content,r,i),tag:"span",classes:["token",e.type],attributes:{},language:r,parent:i};s.type=="comment"&&(s.attributes.spellcheck="true");t.hooks.run("wrap",s);var o="";for(var u in s.attributes)o+=u+'="'+(s.attributes[u]||"")+'"';return"<"+s.tag+' class="'+s.classes.join(" ")+'" '+o+">"+s.content+"</"+s.tag+">"};if(!self.document){self.addEventListener("message",function(e){var n=JSON.parse(e.data),r=n.language,i=n.code;self.postMessage(JSON.stringify(t.tokenize(i,t.languages[r])));self.close()},!1);return}var r=document.getElementsByTagName("script");r=r[r.length-1];if(r){t.filename=r.src;document.addEventListener&&!r.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)}})();;
Prism.languages.markup={comment:/&lt;!--[\w\W]*?-->/g,prolog:/&lt;\?.+?\?>/,doctype:/&lt;!DOCTYPE.+?>/,cdata:/&lt;!\[CDATA\[[\w\W]*?]]>/i,tag:{pattern:/&lt;\/?[\w:-]+\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|\w+))?\s*)*\/?>/gi,inside:{tag:{pattern:/^&lt;\/?[\w:-]+/i,inside:{punctuation:/^&lt;\/?/,namespace:/^[\w-]+?:/}},"attr-value":{pattern:/=(?:('|")[\w\W]*?(\1)|[^\s>]+)/gi,inside:{punctuation:/=|>|"/g}},punctuation:/\/?>/g,"attr-name":{pattern:/[\w:-]+/g,inside:{namespace:/^[\w-]+?:/}}}},entity:/&amp;#?[\da-z]{1,8};/gi};Prism.hooks.add("wrap",function(e){e.type==="entity"&&(e.attributes.title=e.content.replace(/&amp;/,"&"))});;
Prism.languages.css={comment:/\/\*[\w\W]*?\*\//g,atrule:{pattern:/@[\w-]+?.*?(;|(?=\s*{))/gi,inside:{punctuation:/[;:]/g}},url:/url\((["']?).*?\1\)/gi,selector:/[^\{\}\s][^\{\};]*(?=\s*\{)/g,property:/(\b|\B)[\w-]+(?=\s*:)/ig,string:/("|')(\\?.)*?\1/g,important:/\B!important\b/gi,ignore:/&(lt|gt|amp);/gi,punctuation:/[\{\};:]/g};Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{style:{pattern:/(&lt;|<)style[\w\W]*?(>|&gt;)[\w\W]*?(&lt;|<)\/style(>|&gt;)/ig,inside:{tag:{pattern:/(&lt;|<)style[\w\W]*?(>|&gt;)|(&lt;|<)\/style(>|&gt;)/ig,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.css}}});;
Prism.languages.clike={comment:{pattern:/(^|[^\\])(\/\*[\w\W]*?\*\/|(^|[^:])\/\/.*?(\r?\n|$))/g,lookbehind:!0},string:/("|')(\\?.)*?\1/g,"class-name":{pattern:/((?:(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/ig,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|catch|finally|null|break|continue)\b/g,"boolean":/\b(true|false)\b/g,"function":{pattern:/[a-z0-9_]+\(/ig,inside:{punctuation:/\(/}}, number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/g,operator:/[-+]{1,2}|!|&lt;=?|>=?|={1,3}|(&amp;){1,2}|\|?\||\?|\*|\/|\~|\^|\%/g,ignore:/&(lt|gt|amp);/gi,punctuation:/[{}[\];(),.:]/g};;
Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(var|let|if|else|while|do|for|return|in|instanceof|function|new|with|typeof|try|catch|finally|null|break|continue)\b/g,number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?|NaN|-?Infinity)\b/g});Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/g,lookbehind:!0}});Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/(&lt;|<)script[\w\W]*?(>|&gt;)[\w\W]*?(&lt;|<)\/script(>|&gt;)/ig,inside:{tag:{pattern:/(&lt;|<)script[\w\W]*?(>|&gt;)|(&lt;|<)\/script(>|&gt;)/ig,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.javascript}}});;

View file

@ -0,0 +1,201 @@
/* Reset */
html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp, small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, figcaption, figure, footer, header, hgroup, menu, nav, section, summary, time, mark, audio, video { margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline; }
article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { display: block; }
blockquote, q { quotes: none; }
blockquote:before, blockquote:after, q:before, q:after { content: ""; content: none; }
ins { background-color: #ff9; color: #000; text-decoration: none; }
mark { background-color: #ff9; color: #000; font-style: italic; font-weight: bold; }
del { text-decoration: line-through; }
abbr[title], dfn[title] { border-bottom: 1px dotted; cursor: help; }
table { border-collapse: collapse; border-spacing: 0; }
hr { display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0; }
input, select { vertical-align: middle; }
body { font:13px/1.231 sans-serif; *font-size:small; } /* Hack retained to preserve specificity */
select, input, textarea, button { font:99% sans-serif; }
pre, code, kbd, samp { font-family: monospace, sans-serif; }
body { background: #EEE; color: #444; line-height: 1.4em; }
header h1 { color: black; font-size: 2em; line-height: 1.1em; display: inline-block; height: 27px; margin: 20px 0 25px; }
div#content { background: white; border: 1px solid #ccc; border-width: 0 1px 1px; margin: 0 auto; padding: 40px 50px 40px; width: 738px; }
footer { color: #999; padding-top: 40px; font-size: 0.8em; text-align: center; }
body { font-family: sans-serif; font-size: 1em; }
p { margin: 0 0 .7em; max-width: 700px; }
h2 { border-bottom: 1px solid #ccc; font-size: 1.2em; margin: 3em 0 1em 0; font-weight: bold;}
h3 { font-weight: bold; }
h2.intro { border-bottom: none; font-size: 1em; font-weight: normal; margin-top:0; }
ul li { list-style: disc; margin-left: 1em; margin-bottom: 1.25em; }
ol li { margin-left: 1.25em; }
ol ul, ul ul { margin: .25em 0 0; }
ol ul li, ul ul li { list-style-type: circle; margin: 0 0 .25em 1em; }
li > p { margin-top: .25em; }
div.side-by-side { width: 100%; margin-bottom: 1em; }
div.side-by-side > div { float: left; width: 49%; }
div.side-by-side > div > em { margin-bottom: 10px; display: block; }
.faqs em { display: block; }
.clearfix:after {
content: "\0020";
display: block;
height: 0;
clear: both;
overflow: hidden;
visibility: hidden;
}
a { color: #F36C00; outline: none; text-decoration: none; }
a:hover { text-decoration: underline; }
ul.credits li { margin-bottom: .25em; }
strong { font-weight: bold; }
.button {
background: #fafafa;
background: -webkit-linear-gradient(top, #ffffff, #eeeeee);
background: -moz-linear-gradient(top, #ffffff, #eeeeee);
background: -o-linear-gradient(top, #ffffff, #eeeeee);
background: linear-gradient(to bottom, #ffffff, #eeeeee);
border: 1px solid #bbbbbb;
border-radius: 4px;
box-shadow: inset 0 1px 1px rgba(255, 255, 255, 0.2);
color: #555555;
cursor: pointer;
display: inline-block;
font-family: "Helvetica Neue", Arial, Verdana, "Nimbus Sans L", sans-serif;
font-size: 13px;
font-weight: 500;
height: 31px;
line-height: 28px;
outline: none;
padding: 0 13px;
text-shadow: 0 1px 0 white;
text-decoration: none;
vertical-align: middle;
white-space: nowrap;
-webkit-font-smoothing: antialiased;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.button-blue {
background: #1385e5;
background: -webkit-linear-gradient(top, #53b2fc, #1385e5);
background: -moz-linear-gradient(top, #53b2fc, #1385e5);
background: -o-linear-gradient(top, #53b2fc, #1385e5);
background: linear-gradient(to bottom, #53b2fc, #1385e5);
border-color: #075fa9;
color: white;
font-weight: bold;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.4);
}
/* Tweak navbar brand link to be super sleek
-------------------------------------------------- */
.oss-bar {
top: 0;
right: 20px;
position: fixed;
z-index: 1030;
}
.oss-bar ul {
float: right;
margin: 0;
list-style: none;
}
.oss-bar ul li {
list-style: none;
float: left;
line-height: 0;
margin: 0;
}
.oss-bar ul li a {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
border: 0;
margin-top: -10px;
display: block;
height: 58px;
background: #F36C00 url(oss-credit.png) no-repeat 20px 22px;
padding: 22px 20px 12px 20px;
text-indent: 120%; /* stupid padding */
white-space: nowrap;
overflow: hidden;
-webkit-transition: all 0.10s ease-in-out;
-moz-transition: all 0.10s ease-in-out;
transition: all 0.15s ease-in-out;
}
.oss-bar ul li a:hover {
margin-top: 0px;
}
.oss-bar a.harvest {
width: 196px;
background-color: #F36C00;
background-position: -142px 22px;
padding-right: 22px; /* optical illusion */
}
.oss-bar a.fork {
width: 162px;
background-color: #333333;
}
.docs-table th, .docs-table td {
border: 1px solid #000;
padding: 4px 6px;
white-space: nowrap;
}
.docs-table td:last-child {
white-space: normal;
}
.docs-table th {
font-weight: bold;
text-align: left;
}
#content pre[class*=language-] {
font-size: 14px;
margin-bottom: 20px;
}
#content pre[class*=language-] code {
font-size: 14px;
padding: 0;
}
#content code[class*=language-] {
font-size: 12px;
padding: 2px 4px;
}
.anchor {
color: inherit;
position: relative;
}
.anchor:hover {
background: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSI3Ij48ZyBmaWxsPSIjNDE0MDQyIj48cGF0aCBkPSJNOS44IDdoLS45bC0uOS0uMWMtLjctLjMtMS40LS43LTEuOC0xLjMtLjItLjEtLjMtLjMtLjMtLjVsLS4zLS40Yy0uMS0uNC0uMi0uOC0uMi0xLjIgMC0uNC4xLS44LjItMS4yaDEuN2MtLjMuNC0uNC44LS40IDEuMiAwIC40LjEuOC4zIDEuMS4xLjIuMi4zLjQuNC4xLjEuMi4yLjQuMy4zLjIuNy4zIDEgLjNoMy40YzEuMiAwIDIuMi0uOSAyLjItMi4xcy0xLTIuMS0yLjItMi4xaC0xLjRjLS4zLS42LS43LTEtMS4yLTEuNGgyLjZjMiAwIDMuNiAxLjYgMy42IDMuNXMtMS42IDMuNS0zLjYgMy41aC0yLjZ6TTguNCAyYy0uMS0uMS0uMi0uMy0uNC0uMy0uMy0uMi0uNy0uMy0xLS4zaC0zLjRjLTEuMiAwLTIuMi45LTIuMiAyLjEgMCAxLjIgMSAyLjEgMi4yIDIuMWgxLjRjLjMuNS43IDEgMS4yIDEuNGgtMi42Yy0yIDAtMy42LTEuNi0zLjYtMy41czEuNi0zLjUgMy42LTMuNWgzLjUwMDAwMDAwMDAwMDAwMDRsLjkuMWMuNy4yIDEuNC43IDEuOCAxLjMuMS4xLjIuMy4zLjUuMS4xLjIuMy4yLjUuMS40LjIuOC4yIDEuMiAwIC40LS4xLjgtLjIgMS4yaC0xLjZjLjMtLjUuNC0uOS40LTEuM3MtLjEtLjgtLjMtMS4xYy0uMS0uMi0uMi0uMy0uNC0uNHoiLz48L2c+PC9zdmc+) 0 50% no-repeat;
background-size: 21px 9px;
margin-left: -27px;
padding-left: 27px;
text-decoration: none;
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,229 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Chosen: A jQuery Plugin by Harvest to Tame Unwieldy Select Boxes</title>
<link rel="stylesheet" href="docsupport/style.css">
<link rel="stylesheet" href="docsupport/prism.css">
<link rel="stylesheet" href="chosen.css">
<style type="text/css" media="all">
/* fix rtl for demo */
.chosen-rtl .chosen-drop { left: -9000px; }
</style>
</head>
<body>
<div id="container">
<div id="content">
<header>
<h1>Chosen</h1>
</header>
<p>Chosen has a number of options and attributes that allow you to have full control of your select boxes.</p>
<h2><a name="options" class="anchor" href="#options">Options</a></h2>
<p>The following options are available to pass into Chosen on instantiation.</p>
<h3>Example:</h3>
<pre>
<code class="language-javascript">$(".my_select_box").chosen(
disable_search_threshold: 10,
no_results_text: "Oops, nothing found!",
width: "95%"
);</code>
</pre>
<table class="docs-table">
<tr>
<th>Option</th><th>Default</th><th>Description</th>
</tr>
<tr>
<td>allow_single_deselect</td>
<td>false</td>
<td>When set to <code class="language-javascript">true</code> on a single select, Chosen adds a UI element which selects the first elment (if it is blank).</td>
</tr>
<tr>
<td>disable_search</td>
<td>false</td>
<td>When set to <code class="language-javascript">true</code>, Chosen will not display the search field (single selects only).</td>
</tr>
<tr>
<td>disable_search_threshold</td>
<td>0</td>
<td>Hide the search input on single selects if there are fewer than (n) options.</td>
</tr>
<tr>
<td>enable_split_word_search</td>
<td>true</td>
<td>By default, searching will match on any word within an option tag. Set this option to <code class="language-javascript">false</code> if you want to only match on the entire text of an option tag.</td>
</tr>
<tr>
<td>inherit_select_classes</td>
<td>false</td>
<td>When set to <code class="language-javascript">true</code>, Chosen will grab any classes on the original select field and add them to Chosen's container div.</td>
</tr>
<tr>
<tr>
<td>max_selected_options</td>
<td>Infinity</td>
<td>Limits how many options the user can select. When the limit is reached, the <code class="language-javascript">chosen:maxselected</code> event is triggered.</td>
</tr>
<tr>
<td>no_results_text</td>
<td>"No results match"</td>
<td>The text to be displayed when no matching results are found. The current search is shown at the end of the text (e.g.
No reults match "Bad Search").</td>
</tr>
<tr>
<td>placeholder_text_multiple</td>
<td>"Select Some Options"</td>
<td>The text to be displayed as a placeholder when no options are selected for a multiple select.</td>
</tr>
</tr>
<td>placeholder_text_single</td>
<td>"Select an Option"</td>
<td>The text to be displayed as a placeholder when no options are selected for a single select.</td>
</tr>
<tr>
<td>search_contains</td>
<td>false</td>
<td>By default, Chosen's search matches starting at the beginning of a word. Setting this option to <code class="language-javascript">true</code> allows matches starting from anywhere within a word. This is especially useful for options that include a lot of special characters or phrases in ()'s and []'s.</td>
</tr>
<tr>
<td>single_backstroke_delete</td>
<td>true</td>
<td>By default, pressing delete/backspace on multiple selects will remove a selected choice. When <code class="language-javascript">false</code>, pressing delete/backspace will highlight the last choice, and a second press deselects it.</td>
</tr>
<tr>
<td>width</td>
<td>Original select width.</td>
<td>The width of the Chosen select box. By default, Chosen attempts to match the width of the select box you are replacing. If your select is hidden when Chosen is instantiated, you must specify a width or the select will show up with a width of 0.</td>
</tr>
<tr>
<td>display_disabled_options</td>
<td>true</td>
<td>By default, Chosen includes disabled options in search results with a special styling. Setting this option to false will hide disabled results and exclude them from searches.</td>
</tr>
<tr>
<td>display_selected_options</td>
<td>true</td>
<td>
<p>By default, Chosen includes selected options in search results with a special styling. Setting this option to false will hide selected results and exclude them from searches.</p>
<p><strong>Note:</strong> this is for multiple selects only. In single selects, the selected result will always be displayed.</p>
</td>
</tr>
</table>
<h2><a name="attributes" class="anchor" href="#attributes">Attributes</a></h2>
<p>Certain attributes placed on the select tag or its options can be used to configure Chosen.</p>
<h3>Example:</h3>
<pre>
<code class="language-markup">&lt;select class="my_select_box" data-placeholder="Select Your Options"&gt;
&lt;option value="1"&gt;Option 1&lt;/option&gt;
&lt;option value="2" selected&gt;Option 2&lt;/option&gt;
&lt;option value="3" disabled&gt;Option 3&lt;/option&gt;
&lt;/select&gt;</code>
</pre>
<table class="docs-table">
<tr>
<th>Attribute</th><th>Description</th>
</tr>
<tr>
<td>data-placeholder</td>
<td>
</p>The text to be displayed as a placeholder when no options are selected for a select. Defaults to "Select an Option" for single selects or "Select Some Options" for multiple selects.</p>
<p><strong>Note:</strong>This attribute overrides anything set in the <code class="language-javascript">placeholder_text_multiple</code> or <code class="language-javascript">placeholder_text_single</code> options.</p>
</td>
</tr>
<tr>
<td>multiple</td>
<td>The attribute <code class="language-html">multiple</code> on your select box dictates whether Chosen will render a multiple or single select.</td>
</tr>
<tr>
<td>selected, disabled</td>
<td>Chosen automatically highlights selected options and disables disabled options.</td>
</tr>
</table>
<h2><a name="classes" class="anchor" href="#classes">Classes</a></h2>
<p>Classes placed on the select tag can be used to configure Chosen.</p>
<h3>Example:</h3>
<pre>
<code class="language-markup">&lt;select class="my_select_box chosen-rtl"&gt;
&lt;option value="1"&gt;Option 1&lt;/option&gt;
&lt;option value="2"&gt;Option 2&lt;/option&gt;
&lt;option value="3"&gt;Option 3&lt;/option&gt;
&lt;/select&gt;</code>
</pre>
<table class="docs-table">
<tr>
<th>Classname</th>
<th>Description</th>
<tr>
<td>chosen-rtl</td>
<td>
<p>Chosen supports right-to-left text in select boxes. Add the class <code class="language-html">chosen-rtl</code> to your select tag to support right-to-left text options.</p>
<p><strong>Note:</strong> The <code class="language-html">chosen-rtl</code> class will pass through to the Chosen select even when the <code class="language-javascript">inherit_select_classes</code> option is set to <code class="language-javascript">false</code>.</p>
</td>
<tr>
</table>
<h2><a name="events" class="anchor" href="#events">Events</a></h2>
<p>Chosen triggers a number of standard and custom events on the original select field.</p>
<h3>Example:</h3>
<pre>
<code class="language-javascript">$('select').on('change', function(evt, params) {
do_something(evt, params);
});</code>
</pre>
<table class="docs-table">
<tr>
<th>Event</th><th>Description</th>
</tr>
<tr>
<td>change</td>
<td>
<p>Chosen triggers the standard DOM event whenever a selection is made (it also sends a <code class="language-javascript">selected</code> or <code class="language-javascript">deselected</code> parameter that tells you which option was changed).</p>
<p><strong>Note:</strong> in order to use change in the Prototype version, you have to include the <a href="https://github.com/kangax/protolicious/blob/5b56fdafcd7d7662c9d648534225039b2e78e371/event.simulate.js">Event.simulate</a> class. The selected and deselected parameters are not available for Prototype.</p>
</td>
</tr>
<tr>
<td>chosen:ready</td>
<td>after Chosen has been fully instantiated (it also sends the <code class="language-javascript">chosen</code> object as a parameter).</td>
</tr>
<tr>
<td>chosen:maxselected</td>
<td>triggered if <code class="language-javascript">max_selected_options</code> is set and that total is broken. (it also sends the <code class="language-javascript">chosen</code> object as a parameter)</td>
</tr>
<tr>
<td>chosen:showing_dropdown</td>
<td>triggered when Chosen's dropdown is opened (it also sends the <code class="language-javascript">chosen</code> object as a parameter).</td>
</tr>
<tr>
<td>chosen:hiding_dropdown</td>
<td>triggered when Chosen's dropdown is closed (it also sends the <code class="language-javascript">chosen</code> object as a parameter).</td>
</tr>
</table>
<footer>
&copy; 2011&ndash;2013 <a href="http://www.getharvest.com/">Harvest</a>. Chosen is licensed under the <a href="https://github.com/harvesthq/chosen/blob/master/LICENSE.md">MIT license</a>.
</footer>
</div>
</div>
<div class="oss-bar">
<ul>
<li><a class="fork" href="https://github.com/harvesthq/chosen">Fork on Github</a></li>
<li><a class="harvest" href="http://www.getharvest.com/">Built by Harvest</a></li>
</ul>
</div>
<script src="docsupport/prism.js" type="text/javascript" charset="utf-8"></script>
</body>
</html>

View file

@ -0,0 +1,28 @@
// ACCORDION
// ---------
// Parent container
.accordion {
margin-bottom: @baseLineHeight;
}
// Group == heading + body
.accordion-group {
margin-bottom: 2px;
border: 1px solid #e5e5e5;
.border-radius(4px);
}
.accordion-heading {
border-bottom: 0;
}
.accordion-heading .accordion-toggle {
display: block;
padding: 8px 15px;
}
// Inner needs the styles because you can't animate properly with any styles on the element
.accordion-inner {
padding: 9px 15px;
border-top: 1px solid #e5e5e5;
}

View file

@ -0,0 +1,77 @@
// ALERT STYLES
// ------------
// Base alert styles
.alert {
padding: 8px 35px 8px 14px;
margin-bottom: @baseLineHeight;
text-shadow: 0 1px 0 rgba(255,255,255,.5);
background-color: @warningBackground;
border: 1px solid @warningBorder;
.border-radius(4px);
}
.alert,
.alert-heading {
color: @warningText;
}
.message .alert {
.border-radius(0);
height: 24px;
font-size: 14px;
padding: 10px 35px 6px 14px;
}
// Adjust close link position
.alert .close {
position: relative;
top: -2px;
right: -21px;
line-height: 18px;
}
// Alternate styles
// ----------------
.alert-success {
background-color: @successBackground;
border-color: @successBorder;
}
.alert-success,
.alert-success .alert-heading {
color: @successText;
}
.alert-danger,
.alert-error {
background-color: @errorBackground;
border-color: @errorBorder;
}
.alert-danger,
.alert-error,
.alert-danger .alert-heading,
.alert-error .alert-heading {
color: @errorText;
}
.alert-info {
background-color: @infoBackground;
border-color: @infoBorder;
}
.alert-info,
.alert-info .alert-heading {
color: @infoText;
}
// Block alerts
// ------------------------
.alert-block {
padding-top: 14px;
padding-bottom: 14px;
}
.alert-block > p,
.alert-block > ul {
margin-bottom: 0;
}
.alert-block p + p {
margin-top: 5px;
}

View file

@ -0,0 +1,152 @@
// ALERT STYLES
// ------------
// Base alert styles
.alert, .badge {
padding: 8px 35px 8px 14px;
margin-bottom: @baseLineHeight;
text-shadow: 0 1px 0 rgba(255,255,255,.5);
background-color: @warningBackground;
border: 1px solid @warningBorder;
.border-radius(4px);
font-size:10px;
}
.alert {
font-size: 13px;
}
.badge {
padding: 1px 9px 2px;
.border-radius(9px);
border:none;
text-shadow:none;
color:@white;
}
.alert,
.alert-heading {
color: @warningText;
}
// Adjust close link position
.alert .close {
position: relative;
top: -2px;
right: -21px;
line-height: 18px;
}
// Alternate styles
// ----------------
.alert-success {
background-color: @successBackground;
border-color: @successBorder;
}
.alert-success,
.alert-success .alert-heading {
color: @successText;
}
.alert-danger,
.alert-error {
background-color: @errorBackground;
border-color: @errorBorder;
}
.alert-danger,
.alert-error,
.alert-danger .alert-heading,
.alert-error .alert-heading {
color: @errorText;
}
.alert-info {
background-color: @infoBackground;
border-color: @infoBorder;
}
.alert-info,
.alert-info .alert-heading {
color: @infoText;
}
// Block alerts
// ------------------------
.alert-block {
padding-top: 14px;
padding-bottom: 14px;
}
.alert-block > p,
.alert-block > ul {
margin-bottom: 0;
}
.alert-block p + p {
margin-top: 5px;
}
a.label:hover,
a.badge:hover {
color: #ffffff;
text-decoration: none;
cursor: pointer;
}
.label-important,
.badge-important {
background-color: #b94a48;
}
.label-important[href],
.badge-important[href] {
background-color: #953b39;
}
.label-warning,
.badge-warning {
background-color: #f89406;
}
.label-warning[href],
.badge-warning[href] {
background-color: #c67605;
}
.label-success,
.badge-success {
background-color: #468847;
}
.label-success[href],
.badge-success[href] {
background-color: #356635;
}
.label-info,
.badge-info {
background-color: #3a87ad;
}
.label-info[href],
.badge-info[href] {
background-color: #2d6987;
}
.label-inverse,
.badge-inverse {
background-color: #333333;
}
.label-inverse[href],
.badge-inverse[href] {
background-color: #1a1a1a;
}
.btn .label,
.btn .badge {
position: relative;
top: -1px;
}
.btn-mini .label,
.btn-mini .badge {
top: 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 B

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,67 @@
/*!
* Bootstrap v2.0.1
*
* Copyright 2012 Twitter, Inc
* Licensed under the Apache License v2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Designed and built with all the love in the world @twitter by @mdo and @fat.
*/
// CSS Reset
@import "reset.less";
// Core variables and mixins
@import "variables.less"; // Modify this for custom colors, font-sizes, etc
@import "mixins.less";
// Grid system and page structure
@import "scaffolding.less";
@import "grid.less";
@import "layouts.less";
// Base CSS
@import "type.less";
@import "code.less";
@import "forms.less";
@import "tables.less";
@import "alerts.less";
// Upload
@import "fileupload.less";
// Components: common
@import "sprites.less";
@import "dropdowns.less";
@import "wells.less";
@import "component-animations.less";
@import "close.less";
// Components: Buttons & Alerts
@import "buttons.less";
@import "button-groups.less";
@import "alerts_badges.less"; // Note: alerts share common CSS with buttons and thus have styles in buttons.less
// Components: Nav
@import "navs.less";
@import "navbar.less";
@import "breadcrumbs.less";
@import "pagination.less";
@import "pager.less";
// Components: Popovers
@import "modals.less";
@import "tooltip.less";
@import "popovers.less";
// Components: Misc
@import "thumbnails.less";
@import "labels.less";
@import "progress-bars.less";
@import "accordion.less";
@import "carousel.less";
@import "hero-unit.less";
// Utility classes
@import "utilities.less"; // Has to be last to override when necessary

View file

@ -0,0 +1 @@
lessc: ENOENT, No such file or directory '/home/lois/www/repo/www.trinity.fr/trinity/trunk/dev/src/Trinity/Bundle/AdminBundle/Resources/public/css/bootstrap.less'

View file

@ -0,0 +1,22 @@
// BREADCRUMBS
// -----------
.breadcrumb {
padding: 7px 14px;
margin: 0 0 @baseLineHeight;
#gradient > .vertical(@white, #f5f5f5);
border: 1px solid #ddd;
.border-radius(3px);
.box-shadow(inset 0 1px 0 @white);
li {
display: inline-block;
text-shadow: 0 1px 0 @white;
}
.divider {
padding: 0 5px;
color: @grayLight;
}
.active a {
color: @grayDark;
}
}

View file

@ -0,0 +1,148 @@
// BUTTON GROUPS
// -------------
// Make the div behave like a button
.btn-group {
position: relative;
.clearfix(); // clears the floated buttons
.ie7-restore-left-whitespace();
}
// Space out series of button groups
.btn-group + .btn-group {
margin-left: 5px;
}
// Optional: Group multiple button groups together for a toolbar
.btn-toolbar {
//margin-top: @baseLineHeight / 2;
//margin-bottom: @baseLineHeight / 2;
.btn-group {
display: inline-block;
.ie7-inline-block();
}
}
// Float them, remove border radius, then re-add to first and last elements
.btn-group .btn {
position: relative;
float: left;
margin-left: -1px;
.border-radius(0);
}
// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match
.btn-group .btn:first-child {
margin-left: 0;
-webkit-border-top-left-radius: 4px;
-moz-border-radius-topleft: 4px;
border-top-left-radius: 4px;
-webkit-border-bottom-left-radius: 4px;
-moz-border-radius-bottomleft: 4px;
border-bottom-left-radius: 4px;
}
.btn-group .btn:last-child,
.btn-group .dropdown-toggle {
-webkit-border-top-right-radius: 4px;
-moz-border-radius-topright: 4px;
border-top-right-radius: 4px;
-webkit-border-bottom-right-radius: 4px;
-moz-border-radius-bottomright: 4px;
border-bottom-right-radius: 4px;
}
// Reset corners for large buttons
.btn-group .btn.large:first-child {
margin-left: 0;
-webkit-border-top-left-radius: 6px;
-moz-border-radius-topleft: 6px;
border-top-left-radius: 6px;
-webkit-border-bottom-left-radius: 6px;
-moz-border-radius-bottomleft: 6px;
border-bottom-left-radius: 6px;
}
.btn-group .btn.large:last-child,
.btn-group .large.dropdown-toggle {
-webkit-border-top-right-radius: 6px;
-moz-border-radius-topright: 6px;
border-top-right-radius: 6px;
-webkit-border-bottom-right-radius: 6px;
-moz-border-radius-bottomright: 6px;
border-bottom-right-radius: 6px;
}
// On hover/focus/active, bring the proper btn to front
.btn-group .btn:hover,
.btn-group .btn:focus,
.btn-group .btn:active,
.btn-group .btn.active {
z-index: 2;
}
// On active and open, don't show outline
.btn-group .dropdown-toggle:active,
.btn-group.open .dropdown-toggle {
outline: 0;
}
// Split button dropdowns
// ----------------------
// Give the line between buttons some depth
.btn-group .dropdown-toggle {
padding-left: 8px;
padding-right: 8px;
@shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);
.box-shadow(@shadow);
*padding-top: 5px;
*padding-bottom: 5px;
}
.btn-group.open {
// IE7's z-index only goes to the nearest positioned ancestor, which would
// make the menu appear below buttons that appeared later on the page
*z-index: @zindexDropdown;
// Reposition menu on open and round all corners
.dropdown-menu {
display: block;
margin-top: 1px;
.border-radius(5px);
}
.dropdown-toggle {
background-image: none;
@shadow: inset 0 1px 6px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);
.box-shadow(@shadow);
}
}
// Reposition the caret
.btn .caret {
margin-top: 7px;
margin-left: 0;
}
.btn:hover .caret,
.open.btn-group .caret {
.opacity(100);
}
// Account for other colors
.btn-primary,
.btn-danger,
.btn-info,
.btn-success,
.btn-inverse {
.caret {
border-top-color: @white;
.opacity(75);
}
}
// Small button dropdowns
.btn-small .caret {
margin-top: 4px;
}

View file

@ -0,0 +1,183 @@
// BUTTON STYLES
// -------------
// Base styles
// --------------------------------------------------
// Core
.btn {
display: inline-block;
padding: 4px 10px 4px;
margin-bottom: 0; // For input.btn
font-size: @baseFontSize;
line-height: @baseLineHeight;
color: @grayDark;
text-align: center;
text-shadow: 0 1px 1px rgba(255,255,255,.75);
vertical-align: middle;
.buttonBackground(@white, darken(@white, 10%));
border: 1px solid #ccc;
border-bottom-color: #bbb;
.border-radius(4px);
@shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);
.box-shadow(@shadow);
cursor: pointer;
// Give IE7 some love
.reset-filter();
.ie7-restore-left-whitespace();
}
// Hover state
.btn:hover {
color: @grayDark;
text-decoration: none;
background-color: darken(@white, 10%);
background-position: 0 -15px;
// transition is only when going to hover, otherwise the background
// behind the gradient (there for IE<=9 fallback) gets mismatched
.transition(background-position .1s linear);
}
// Focus state for keyboard and accessibility
.btn:focus {
.tab-focus();
}
// Active state
.btn.active,
.btn:active {
background-image: none;
@shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);
.box-shadow(@shadow);
background-color: darken(@white, 10%);
background-color: darken(@white, 15%) e("\9");
outline: 0;
}
// Disabled state
.btn.disabled,
.btn[disabled] {
cursor: default;
background-image: none;
background-color: darken(@white, 10%);
.opacity(65);
.box-shadow(none);
}
// Button Sizes
// --------------------------------------------------
// Large
.btn-large {
padding: 9px 14px;
//font-size: @baseFontSize + 2px;
line-height: normal;
.border-radius(5px);
}
.btn-large [class^="icon-"] {
margin-top: 1px;
}
// Small
.btn-small {
padding: 5px 9px;
//font-size: @baseFontSize - 2px;
//line-height: @baseLineHeight - 2px;
}
.btn-small [class^="icon-"] {
margin-top: -1px;
}
// Mini
.btn-mini {
padding: 2px 6px;
//font-size: @baseFontSize - 2px;
//line-height: @baseLineHeight - 4px;
}
// Alternate buttons
// --------------------------------------------------
// Set text color
// -------------------------
.btn-primary,
.btn-primary:hover,
.btn-warning,
.btn-warning:hover,
.btn-danger,
.btn-danger:hover,
.btn-success,
.btn-success:hover,
.btn-info,
.btn-info:hover,
.btn-inverse,
.btn-inverse:hover {
text-shadow: 0 -1px 0 rgba(0,0,0,.25);
color: @white;
}
// Provide *some* extra contrast for those who can get it
.btn-primary.active,
.btn-warning.active,
.btn-danger.active,
.btn-success.active,
.btn-info.active,
.btn-dark.active {
color: rgba(255,255,255,.75);
}
// Set the backgrounds
// -------------------------
.btn-primary {
.buttonBackground(#00abdf, #2c6a99); /* #00b3cc, #0074cc */
}
// Warning appears are orange
.btn-warning {
.buttonBackground(#ff7d48, #ff4a01); /* lighten(@orange, 15%), @orange */
}
// Danger and error appear as red
.btn-danger {
.buttonBackground(#db4e53, #b1292c); /* #ee5f5b et #bd362f */
}
// Success appears as green
.btn-success {
.buttonBackground(#61c2b5 ,#52a499);
}
// Info appears as a neutral blue
.btn-info {
.buttonBackground(#5bc0de, #2f96b4); /*5bc0de et 2f96b4 || 00abdf et 2986a2*/
}
// Inverse appears as dark gray
.btn-inverse {
.buttonBackground(#454545, #262626);
}
// Cross-browser Jank
// --------------------------------------------------
button.btn,
input[type="submit"].btn {
// Firefox 3.6 only I believe
&::-moz-focus-inner {
padding: 0;
border: 0;
}
// IE7 has some default padding on button controls
*padding-top: 2px;
*padding-bottom: 2px;
&.large {
*padding-top: 7px;
*padding-bottom: 7px;
}
&.small {
*padding-top: 3px;
*padding-bottom: 3px;
}
}

View file

@ -0,0 +1,121 @@
// CAROUSEL
// --------
.carousel {
position: relative;
margin-bottom: @baseLineHeight;
line-height: 1;
}
.carousel-inner {
overflow: hidden;
width: 100%;
position: relative;
}
.carousel {
.item {
display: none;
position: relative;
.transition(.6s ease-in-out left);
}
// Account for jankitude on images
.item > img {
display: block;
line-height: 1;
}
.active,
.next,
.prev { display: block; }
.active {
left: 0;
}
.next,
.prev {
position: absolute;
top: 0;
width: 100%;
}
.next {
left: 100%;
}
.prev {
left: -100%;
}
.next.left,
.prev.right {
left: 0;
}
.active.left {
left: -100%;
}
.active.right {
left: 100%;
}
}
// Left/right controls for nav
// ---------------------------
.carousel-control {
position: absolute;
top: 40%;
left: 15px;
width: 40px;
height: 40px;
margin-top: -20px;
font-size: 60px;
font-weight: 100;
line-height: 30px;
color: @white;
text-align: center;
background: @grayDarker;
border: 3px solid @white;
.border-radius(23px);
.opacity(50);
// we can't have this transition here
// because webkit cancels the carousel
// animation if you trip this while
// in the middle of another animation
// ;_;
// .transition(opacity .2s linear);
// Reposition the right one
&.right {
left: auto;
right: 15px;
}
// Hover state
&:hover {
color: @white;
text-decoration: none;
.opacity(90);
}
}
// Caption for text below images
// -----------------------------
.carousel-caption {
position: absolute;
left: 0;
right: 0;
bottom: 0;
padding: 10px 15px 5px;
background: @grayDark;
background: rgba(0,0,0,.75);
}
.carousel-caption h4,
.carousel-caption p {
color: @white;
}

View file

@ -0,0 +1,18 @@
// CLOSE ICONS
// -----------
.close {
float: right;
font-size: 20px;
font-weight: bold;
line-height: @baseLineHeight;
color: @black;
text-shadow: 0 1px 0 rgba(255,255,255,1);
.opacity(20);
&:hover {
color: @black;
text-decoration: none;
.opacity(40);
cursor: pointer;
}
}

View file

@ -0,0 +1,57 @@
// Code.less
// Code typography styles for the <code> and <pre> elements
// --------------------------------------------------------
// Inline and block code styles
code,
pre {
padding: 0 3px 2px;
#font > #family > .monospace;
//font-size: @baseFontSize - 1;
color: @grayDark;
.border-radius(3px);
}
// Inline code
code {
padding: 3px 4px;
color: #d14;
background-color: #f7f7f9;
border: 1px solid #e1e1e8;
}
// Blocks of code
pre {
display: block;
//padding: (@baseLineHeight - 1) / 2;
//margin: 0 0 @baseLineHeight / 2;
font-size: 12px;
line-height: @baseLineHeight;
background-color: #f5f5f5;
border: 1px solid #ccc; // fallback for IE7-8
border: 1px solid rgba(0,0,0,.15);
.border-radius(4px);
white-space: pre;
white-space: pre-wrap;
word-break: break-all;
word-wrap: break-word;
// Make prettyprint styles more spaced out for readability
&.prettyprint {
margin-bottom: @baseLineHeight;
}
// Account for some code outputs that place code tags in pre tags
code {
padding: 0;
color: inherit;
background-color: transparent;
border: 0;
}
}
// Enable scrollable blocks of code
.pre-scrollable {
max-height: 340px;
overflow-y: scroll;
}

View file

@ -0,0 +1,18 @@
// COMPONENT ANIMATIONS
// --------------------
.fade {
.transition(opacity .15s linear);
opacity: 0;
&.in {
opacity: 1;
}
}
.collapse {
.transition(height .35s ease);
position:relative;
overflow:hidden;
height: 0;
&.in { height: auto; }
}

View file

@ -0,0 +1,128 @@
// DROPDOWN MENUS
// --------------
// Use the .menu class on any <li> element within the topbar or ul.tabs and you'll get some superfancy dropdowns
.dropdown {
position: relative;
}
.dropdown-toggle {
// The caret makes the toggle a bit too tall in IE7
*margin-bottom: -3px;
}
.dropdown-toggle:active,
.open .dropdown-toggle {
outline: 0;
}
// Dropdown arrow/caret
.caret {
display: inline-block;
width: 0;
height: 0;
text-indent: -99999px;
// IE7 won't do the border trick if there's a text indent, but it doesn't
// do the content that text-indent is hiding, either, so we're ok.
*text-indent: 0;
vertical-align: top;
border-left: 4px solid transparent;
border-right: 4px solid transparent;
border-top: 4px solid @black;
.opacity(30);
content: "\2193";
}
.dropdown .caret {
margin-top: 8px;
margin-left: 2px;
}
.dropdown:hover .caret,
.open.dropdown .caret {
.opacity(100);
}
// The dropdown menu (ul)
.dropdown-menu {
position: absolute;
top: 100%;
left: 0;
z-index: @zindexDropdown;
float: left;
display: none; // none by default, but block on "open" of the menu
min-width: 160px;
_width: 160px;
padding: 4px 0;
margin: 0; // override default ul
list-style: none;
background-color: @white;
border-color: #ccc;
border-color: rgba(0,0,0,.2);
border-style: solid;
border-width: 1px;
.border-radius(0 0 5px 5px);
.box-shadow(0 5px 10px rgba(0,0,0,.2));
-webkit-background-clip: padding-box;
-moz-background-clip: padding;
background-clip: padding-box;
*border-right-width: 2px;
*border-bottom-width: 2px;
// Allow for dropdowns to go bottom up (aka, dropup-menu)
&.bottom-up {
top: auto;
bottom: 100%;
margin-bottom: 2px;
}
// Dividers (basically an hr) within the dropdown
.divider {
height: 1px;
margin: 5px 1px;
overflow: hidden;
background-color: #e5e5e5;
border-bottom: 1px solid @white;
// IE7 needs a set width since we gave a height. Restricting just
// to IE7 to keep the 1px left/right space in other browsers.
// It is unclear where IE is getting the extra space that we need
// to negative-margin away, but so it goes.
*width: 100%;
*margin: -5px 0 5px;
}
// Links within the dropdown menu
a {
display: block;
padding: 5px 25px;
clear: both;
font-weight: normal;
line-height: @baseLineHeight;
color: @gray;
white-space: nowrap;
}
}
// Hover state
.dropdown-menu li > a:hover,
.dropdown-menu .active > a,
.dropdown-menu .active > a:hover {
color: @white;
text-decoration: none;
background-color: @linkColor;
}
// Open state for the dropdown
.dropdown.open {
// IE7's z-index only goes to the nearest positioned ancestor, which would
// make the menu appear below buttons that appeared later on the page
*z-index: @zindexDropdown;
.dropdown-toggle {
color: @gray;
}
.dropdown-menu {
display: block;
}
}
// Typeahead
.typeahead {
margin-top: 2px; // give it some space to breathe
.border-radius(4px);
}

View file

@ -0,0 +1,132 @@
/*!
* Bootstrap v2.3.0-j4
*
* Copyright 2012 Twitter, Inc
* Licensed under the Apache License v2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Designed and built with all the love in the world by @mdo and @fat, extended by @ArnoldDaniels.
*/
.clearfix {
*zoom: 1;
}
.clearfix:before,
.clearfix:after {
display: table;
content: "";
line-height: 0;
}
.clearfix:after {
clear: both;
}
.hide-text {
font: 0/0 a;
color: transparent;
text-shadow: none;
background-color: transparent;
border: 0;
}
.input-block-level {
display: block;
width: 100%;
min-height: 30px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.btn-file {
overflow: hidden;
position: relative;
vertical-align: middle;
}
.btn-file > input {
position: absolute;
top: 0;
right: 0;
margin: 0;
opacity: 0;
filter: alpha(opacity=0);
transform: translate(-300px, 0) scale(4);
font-size: 23px;
direction: ltr;
cursor: pointer;
}
.fileupload {
margin-bottom: 9px;
}
.fileupload .uneditable-input {
display: inline-block;
margin-bottom: 0px;
vertical-align: middle;
cursor: text;
}
.fileupload .thumbnail {
overflow: hidden;
display: inline-block;
margin-bottom: 5px;
vertical-align: middle;
text-align: center;
}
.fileupload .thumbnail > img {
display: inline-block;
vertical-align: middle;
max-height: 100%;
}
.fileupload .btn {
vertical-align: middle;
}
.fileupload-exists .fileupload-new,
.fileupload-new .fileupload-exists {
display: none;
}
.fileupload-inline .fileupload-controls {
display: inline;
}
.fileupload-new .input-append .btn-file {
-webkit-border-radius: 0 3px 3px 0;
-moz-border-radius: 0 3px 3px 0;
border-radius: 0 3px 3px 0;
}
.thumbnail-borderless .thumbnail {
border: none;
padding: 0;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
}
.fileupload-new.thumbnail-borderless .thumbnail {
border: 1px solid #ddd;
}
.control-group.warning .fileupload .uneditable-input {
color: #a47e3c;
border-color: #a47e3c;
}
.control-group.warning .fileupload .fileupload-preview {
color: #a47e3c;
}
.control-group.warning .fileupload .thumbnail {
border-color: #a47e3c;
}
.control-group.error .fileupload .uneditable-input {
color: #b94a48;
border-color: #b94a48;
}
.control-group.error .fileupload .fileupload-preview {
color: #b94a48;
}
.control-group.error .fileupload .thumbnail {
border-color: #b94a48;
}
.control-group.success .fileupload .uneditable-input {
color: #468847;
border-color: #468847;
}
.control-group.success .fileupload .fileupload-preview {
color: #468847;
}
.control-group.success .fileupload .thumbnail {
border-color: #468847;
}

View file

@ -0,0 +1,522 @@
// Forms.less
// Base styles for various input types, form layouts, and states
// -------------------------------------------------------------
// GENERAL STYLES
// --------------
// Make all forms have space below them
form {
margin: 0 0 @baseLineHeight;
}
fieldset {
padding: 0;
margin: 0;
border: 0;
}
// Groups of fields with labels on top (legends)
legend {
display: block;
width: 100%;
padding: 0;
//margin-bottom: @baseLineHeight * 1.5;
//font-size: @baseFontSize * 1.5;
//line-height: @baseLineHeight * 2;
color: @grayDark;
border: 0;
border-bottom: 1px solid #eee;
// Small
small {
//font-size: @baseLineHeight * .75;
color: @grayLight;
}
}
// Set font for forms
label,
input,
button,
select,
textarea {
#font > .shorthand(@baseFontSize,normal,@baseLineHeight); // Set size, weight, line-height here
}
input,
button,
select,
textarea {
#font > #family > .sans-serif(); // And only set font-family here for those that need it (note the missing label element)
}
// Identify controls by their labels
label {
display: block;
margin-bottom: 5px;
color: @grayDark;
}
// Inputs, Textareas, Selects
input,
textarea,
select,
.uneditable-input {
display: inline-block;
width: 210px;
height: @baseLineHeight;
padding: 4px;
margin-bottom: 9px;
font-size: @baseFontSize;
line-height: @baseLineHeight;
color: @gray;
border: 1px solid #ccc;
.border-radius(3px);
}
.uneditable-textarea {
width: auto;
height: auto;
}
// Inputs within a label
label input,
label textarea,
label select {
display: block;
}
// Mini reset for unique input types
input[type="image"],
input[type="checkbox"],
input[type="radio"] {
width: auto;
height: auto;
padding: 0;
margin: 3px 0;
*margin-top: 0; /* IE7 */
line-height: normal;
cursor: pointer;
.border-radius(0);
border: 0 \9; /* IE9 and down */
}
input[type="image"] {
border: 0;
}
// Reset the file input to browser defaults
input[type="file"] {
width: auto;
padding: initial;
line-height: initial;
border: initial;
background-color: @white;
background-color: initial;
.box-shadow(none);
}
// Help out input buttons
input[type="button"],
input[type="reset"],
input[type="submit"] {
width: auto;
height: auto;
}
// Set the height of select and file controls to match text inputs
select,
input[type="file"] {
height: 28px; /* In IE7, the height of the select element cannot be changed by height, only font-size */
*margin-top: 4px; /* For IE7, add top margin to align select with labels */
line-height: 28px;
}
// Reset line-height for IE
input[type="file"] {
line-height: 18px \9;
}
// Chrome on Linux and Mobile Safari need background-color
select {
width: 220px; // default input width + 10px of padding that doesn't get applied
background-color: @white;
}
// Make multiple select elements height not fixed
select[multiple],
select[size] {
height: auto;
}
// Remove shadow from image inputs
input[type="image"] {
.box-shadow(none);
}
// Make textarea height behave
textarea {
height: auto;
}
// Hidden inputs
input[type="hidden"] {
display: none;
}
// CHECKBOXES & RADIOS
// -------------------
// Indent the labels to position radios/checkboxes as hanging
.radio,
.checkbox {
padding-left: 18px;
}
.radio input[type="radio"],
.checkbox input[type="checkbox"] {
float: left;
margin-left: -18px;
}
// Move the options list down to align with labels
.controls > .radio:first-child,
.controls > .checkbox:first-child {
padding-top: 5px; // has to be padding because margin collaspes
}
// Radios and checkboxes on same line
// TODO v3: Convert .inline to .control-inline
.radio.inline,
.checkbox.inline {
display: inline-block;
padding-top: 5px;
margin-bottom: 0;
vertical-align: middle;
}
.radio.inline + .radio.inline,
.checkbox.inline + .checkbox.inline {
margin-left: 10px; // space out consecutive inline controls
}
// FOCUS STATE
// -----------
input,
textarea {
.box-shadow(inset 0 1px 1px rgba(0,0,0,.075));
@transition: border linear .2s, box-shadow linear .2s;
.transition(@transition);
}
input:focus,
textarea:focus {
border-color: rgba(82,168,236,.8);
@shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6);
.box-shadow(@shadow);
outline: 0;
outline: thin dotted \9; /* IE6-9 */
}
input[type="file"]:focus,
input[type="radio"]:focus,
input[type="checkbox"]:focus,
select:focus {
.box-shadow(none); // override for file inputs
.tab-focus();
}
// INPUT SIZES
// -----------
// General classes for quick sizes
.input-mini { width: 60px; }
.input-small { width: 90px; }
.input-medium { width: 150px; }
.input-large { width: 210px; }
.input-xlarge { width: 270px; }
.input-xxlarge { width: 530px; }
// Grid style input sizes
input[class*="span"],
select[class*="span"],
textarea[class*="span"],
.uneditable-input {
float: none;
margin-left: 0;
}
// GRID SIZING FOR INPUTS
// ----------------------
#inputGridSystem > .generate(@gridColumns, @gridColumnWidth, @gridGutterWidth);
// DISABLED STATE
// --------------
// Disabled and read-only inputs
input[disabled],
select[disabled],
textarea[disabled],
input[readonly],
select[readonly],
textarea[readonly] {
background-color: #f5f5f5;
border-color: #ddd;
cursor: not-allowed;
}
// FORM FIELD FEEDBACK STATES
// --------------------------
// Warning
.control-group.warning {
.formFieldState(@warningText, @warningText, @warningBackground);
}
// Error
.control-group.error {
.formFieldState(@errorText, @errorText, @errorBackground);
}
// Success
.control-group.success {
.formFieldState(@successText, @successText, @successBackground);
}
// HTML5 invalid states
// Shares styles with the .control-group.error above
input:focus:required:invalid,
textarea:focus:required:invalid,
select:focus:required:invalid {
color: #b94a48;
border-color: #ee5f5b;
&:focus {
border-color: darken(#ee5f5b, 10%);
.box-shadow(0 0 6px lighten(#ee5f5b, 20%));
}
}
// FORM ACTIONS
// ------------
.form-actions {
padding: (@baseLineHeight - 1) 20px @baseLineHeight;
margin-top: @baseLineHeight;
margin-bottom: @baseLineHeight;
background-color: #f5f5f5;
border-top: 1px solid #ddd;
}
// For text that needs to appear as an input but should not be an input
.uneditable-input {
display: block;
background-color: @white;
border-color: #eee;
.box-shadow(inset 0 1px 2px rgba(0,0,0,.025));
cursor: not-allowed;
}
// Placeholder text gets special styles; can't be bundled together though for some reason
.placeholder(@grayLight);
// HELP TEXT
// ---------
.help-block {
display: block; // account for any element using help-block
margin-top: 5px;
margin-bottom: 0;
color: @grayLight;
}
.help-inline {
display: inline-block;
.ie7-inline-block();
margin-bottom: 9px;
vertical-align: middle;
padding-left: 5px;
}
// INPUT GROUPS
// ------------
// Allow us to put symbols and text within the input field for a cleaner look
.input-prepend,
.input-append {
margin-bottom: 5px;
.clearfix(); // Clear the float to prevent wrapping
input,
.uneditable-input {
.border-radius(0 3px 3px 0);
&:focus {
position: relative;
z-index: 2;
}
}
.uneditable-input {
border-left-color: #ccc;
}
.add-on {
float: left;
display: block;
width: auto;
min-width: 16px;
height: @baseLineHeight;
margin-right: -1px;
padding: 4px 5px;
font-weight: normal;
line-height: @baseLineHeight;
color: @grayLight;
text-align: center;
text-shadow: 0 1px 0 @white;
background-color: #f5f5f5;
border: 1px solid #ccc;
.border-radius(3px 0 0 3px);
}
.active {
background-color: lighten(@green, 30);
border-color: @green;
}
}
.input-prepend {
.add-on {
*margin-top: 1px; /* IE6-7 */
}
}
.input-append {
input,
.uneditable-input {
float: left;
.border-radius(3px 0 0 3px);
}
.uneditable-input {
border-left-color: #eee;
border-right-color: #ccc;
}
.add-on {
margin-right: 0;
margin-left: -1px;
.border-radius(0 3px 3px 0);
}
input:first-child {
// In IE7, having a hasLayout container (from clearfix's zoom:1) can make the first input
// inherit the sum of its ancestors' margins.
*margin-left: -160px;
&+.add-on {
*margin-left: -21px;
}
}
}
// SEARCH FORM
// -----------
.search-query {
padding-left: 14px;
padding-right: 14px;
margin-bottom: 0; // remove the default margin on all inputs
.border-radius(14px);
}
// HORIZONTAL & VERTICAL FORMS
// ---------------------------
// Common properties
// -----------------
.form-search,
.form-inline,
.form-horizontal {
input,
textarea,
select,
.help-inline,
.uneditable-input {
display: inline-block;
margin-bottom: 0;
}
// Re-hide hidden elements due to specifity
.hide {
display: none;
}
}
.form-search label,
.form-inline label,
.form-search .input-append,
.form-inline .input-append,
.form-search .input-prepend,
.form-inline .input-prepend {
display: inline-block;
}
// Make the prepend and append add-on vertical-align: middle;
.form-search .input-append .add-on,
.form-inline .input-prepend .add-on,
.form-search .input-append .add-on,
.form-inline .input-prepend .add-on {
vertical-align: middle;
}
// Inline checkbox/radio labels
.form-search .radio,
.form-inline .radio,
.form-search .checkbox,
.form-inline .checkbox {
margin-bottom: 0;
vertical-align: middle;
}
// Margin to space out fieldsets
.control-group {
//margin-bottom: @baseLineHeight / 2;
}
// Legend collapses margin, so next element is responsible for spacing
legend + .control-group {
margin-top: @baseLineHeight;
-webkit-margin-top-collapse: separate;
}
// Horizontal-specific styles
// --------------------------
.form-horizontal {
// Increase spacing between groups
.control-group {
margin-bottom: @baseLineHeight;
.clearfix();
}
// Float the labels left
.control-label {
float: left;
width: 140px;
padding-top: 5px;
text-align: right;
}
// Move over all input controls and content
.controls {
margin-left: 160px;
}
// Move over buttons in .form-actions to align with .controls
.form-actions {
padding-left: 160px;
}
}

View file

@ -0,0 +1,8 @@
// GRID SYSTEM
// -----------
// Fixed (940px)
#gridSystem > .generate(@gridColumns, @gridColumnWidth, @gridGutterWidth);
// Fluid (940px)
#fluidGridSystem > .generate(@gridColumns, @fluidGridColumnWidth, @fluidGridGutterWidth);

View file

@ -0,0 +1,20 @@
// HERO UNIT
// ---------
.hero-unit {
padding: 60px;
margin-bottom: 30px;
background-color: #f5f5f5;
.border-radius(6px);
h1 {
margin-bottom: 0;
font-size: 60px;
line-height: 1;
letter-spacing: -1px;
}
p {
font-size: 18px;
font-weight: 200;
//line-height: @baseLineHeight * 1.5;
}
}

View file

@ -0,0 +1,145 @@
/*!
* jQuery contextMenu - Plugin for simple contextMenu handling
*
* Version: 1.6.5
*
* Authors: Rodney Rehm, Addy Osmani (patches for FF)
* Web: http://medialize.github.com/jQuery-contextMenu/
*
* Licensed under
* MIT License http://www.opensource.org/licenses/mit-license
* GPL v3 http://opensource.org/licenses/GPL-3.0
*
*/
.context-menu-list {
margin:0;
padding:0;
min-width: 120px;
max-width: 250px;
display: inline-block;
position: absolute;
list-style-type: none;
border: 1px solid #DDD;
background: #EEE;
-webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5);
-moz-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5);
-ms-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5);
-o-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5);
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5);
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
}
.context-menu-item {
padding: 4px 4px 4px 20px;
background-color: #EEE;
position: relative;
-webkit-user-select: none;
-moz-user-select: -moz-none;
-ms-user-select: none;
user-select: none;
}
.admin-item-icon{
padding: 4px;
}
.context-menu-separator {
padding-bottom:0;
border-bottom: 1px solid #DDD;
}
.context-menu-item > label > input,
.context-menu-item > label > textarea {
-webkit-user-select: text;
-moz-user-select: text;
-ms-user-select: text;
user-select: text;
}
.context-menu-item.hover {
cursor: pointer;
background-color: #ddd;
}
.context-menu-item.disabled {
color: #666;
}
.context-menu-input.hover,
.context-menu-item.disabled.hover {
cursor: default;
background-color: #EEE;
}
.context-menu-submenu:after {
content: ">";
color: #666;
position: absolute;
top: 0;
right: 3px;
z-index: 1;
}
/* icons
#protip:
In case you want to use sprites for icons (which I would suggest you do) have a look at
http://css-tricks.com/13224-pseudo-spriting/ to get an idea of how to implement
.context-menu-item.icon:before {}
*/
.context-menu-item.ct-icon { min-height: 18px; background-repeat: no-repeat; background-position: 3px 6px; }
.context-menu-item.ct-icon-drag { background-image: url(../img/ct/drag.png); }
.context-menu-item.ct-icon-add { background-image: url(../img/ct/add.png); }
.context-menu-item.ct-icon-edit { background-image: url(../img/ct/edit.png); }
.context-menu-item.ct-icon-remove { background-image: url(../img/ct/remove.png); }
.context-menu-item.ct-icon-edit-page { background-image: url(../img/ct/edit-page.png); }
/* vertically align inside labels */
.context-menu-input > label > * { vertical-align: top; }
/* position checkboxes and radios as icons */
.context-menu-input > label > input[type="checkbox"],
.context-menu-input > label > input[type="radio"] {
margin-left: -17px;
}
.context-menu-input > label > span {
margin-left: 5px;
}
.context-menu-input > label,
.context-menu-input > label > input[type="text"],
.context-menu-input > label > textarea,
.context-menu-input > label > select {
display: block;
width: 100%;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
-o-box-sizing: border-box;
box-sizing: border-box;
}
.context-menu-input > label > textarea {
height: 100px;
}
.context-menu-item > .context-menu-list {
display: none;
/* re-positioned by js */
right: -5px;
top: 5px;
}
.context-menu-item.hover > .context-menu-list {
display: block;
}
.context-menu-accesskey {
text-decoration: underline;
}

View file

@ -0,0 +1,10 @@
.ui-timepicker-div .ui-widget-header { margin-bottom: 8px; }
.ui-timepicker-div dl { text-align: left; }
.ui-timepicker-div dl dt { height: 25px; margin-bottom: -25px; }
.ui-timepicker-div dl dd { margin: 0 10px 10px 65px; }
.ui-timepicker-div td { font-size: 90%; }
.ui-tpicker-grid-label { background: none; border: none; margin: 0; padding: 0; }
.ui-timepicker-rtl{ direction: rtl; }
.ui-timepicker-rtl dl { text-align: right; }
.ui-timepicker-rtl dl dd { margin: 0 65px 10px 10px; }

View file

@ -0,0 +1,32 @@
// LABELS
// ------
// Base
.label {
padding: 2px 4px 3px;
//font-size: @baseFontSize * .85;
font-weight: bold;
color: @white;
text-shadow: 0 -1px 0 rgba(0,0,0,.25);
background-color: @grayLight;
.border-radius(3px);
}
// Hover state
.label:hover {
color: @white;
text-decoration: none;
}
// Colors
.label-important { background-color: @errorText; }
.label-important:hover { background-color: darken(@errorText, 10%); }
.label-warning { background-color: @orange; }
.label-warning:hover { background-color: darken(@orange, 10%); }
.label-success { background-color: @successText; }
.label-success:hover { background-color: darken(@successText, 10%); }
.label-info { background-color: @infoText; }
.label-info:hover { background-color: darken(@infoText, 10%); }

View file

@ -0,0 +1,17 @@
//
// Layouts
// Fixed-width and fluid (with sidebar) layouts
// --------------------------------------------
// Container (centered, fixed-width layouts)
.container {
.container-fixed();
}
// Fluid layouts (left aligned, with sidebar, min- & max-width content)
.container-fluid {
padding-left: @gridGutterWidth;
padding-right: @gridGutterWidth;
.clearfix();
}

View file

@ -0,0 +1,174 @@
/*** ESSENTIAL STYLES ***/
.sf-menu,
.sf-menu * {
margin: 0;
padding: 0;
list-style: none;
}
.sf-menu li {
position: relative;
}
.sf-menu ul {
position: absolute;
display: none;
top: 100%;
left: 0;
z-index: 99;
}
.sf-menu > li {
float: left;
}
.sf-menu li:hover > ul,
.sf-menu li.sfHover > ul {
display: block;
}
.sf-menu a {
display: block;
position: relative;
}
.sf-menu ul ul {
top: 0;
left: 100%;
}
/*** DEMO SKIN ***/
.sf-menu {
float: left;
}
.sf-menu ul {
box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.2);
min-width: 12em;
/* allow long menu items to determine submenu width */
*width: 12em;
/* no auto sub width for IE7, see white-space comment below */
}
.sf-menu a {
/* fallback colour must use full shorthand */
padding: .75em 1em;
text-decoration: none;
zoom: 1;
/* IE7 */
}
.sf-menu li ul a {
margin-left: 22px;
}
.sf-menu > li > a {
color: #fff;
}
.sf-menu > li:hover a {
color: #333;
}
.sf-menu li {
white-space: nowrap;
/* no need for Supersubs plugin */
*white-space: normal;
/* ...unless you support IE7 (let it wrap) */
-webkit-transition: background .2s;
transition: background .2s;
}
.sf-menu ul li {
background: #FBFAFA;
}
.sf-menu ul ul li {
background: #FBFAFA;
}
.sf-menu li:hover,
.sf-menu li.sfHover {
background: #E9E9E9;
/* only transition out, not in */
-webkit-transition: none;
transition: none;
}
.sf-menu > li {
line-height: 25px;
height: 41px;
vertical-align: middle;
}
.sf-menu > li:hover {
background: #333;
}
.sf-menu > li:hover > a {
color: #fefefe;
}
/*** arrows (for all except IE7) **/
.sf-arrows .sf-with-ul {
padding-right: 2.5em;
*padding-right: 1em;
/* no CSS arrows for IE7 (lack pseudo-elements) */
}
/* styling for both css and generated arrows */
.sf-arrows .sf-with-ul:after {
content: '';
position: absolute;
top: 50%;
right: 1em;
margin-top: -3px;
height: 0;
width: 0;
/* order of following 3 rules important for fallbacks to work */
border: 5px solid transparent;
border-top-color: #dFeEFF;
/* edit this to suit design (no rgba in IE8) */
border-top-color: rgba(255, 255, 255, 0.5);
}
.sf-arrows > li > .sf-with-ul:focus:after,
.sf-arrows > li:hover > .sf-with-ul:after,
.sf-arrows > .sfHover > .sf-with-ul:after {
border-top-color: white;
/* IE8 fallback colour */
}
/* styling for right-facing arrows */
.sf-arrows ul .sf-with-ul:after {
margin-top: -5px;
margin-right: -3px;
border-color: transparent;
border-left-color: #dFeEFF;
/* edit this to suit design (no rgba in IE8) */
border-left-color: rgba(255, 255, 255, 0.5);
}
.sf-arrows ul li > .sf-with-ul:focus:after,
.sf-arrows ul li:hover > .sf-with-ul:after,
.sf-arrows ul .sfHover > .sf-with-ul:after {
border-left-color: white;
}
.sf-menu li > img {
width: 18px;
position: absolute;
margin-top: 8px;
margin-left: 10px;
}

View file

@ -0,0 +1,590 @@
// Mixins.less
// Snippets of reusable CSS to develop faster and keep code readable
// -----------------------------------------------------------------
// UTILITY MIXINS
// --------------------------------------------------
// Clearfix
// --------
// For clearing floats like a boss h5bp.com/q
.clearfix {
*zoom: 1;
&:before,
&:after {
display: table;
content: "";
}
&:after {
clear: both;
}
}
// Webkit-style focus
// ------------------
.tab-focus() {
// Default
outline: thin dotted #333;
// Webkit
outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px;
}
// Center-align a block level element
// ----------------------------------
.center-block() {
display: block;
margin-left: auto;
margin-right: auto;
}
// IE7 inline-block
// ----------------
.ie7-inline-block() {
*display: inline; /* IE7 inline-block hack */
*zoom: 1;
}
// IE7 likes to collapse whitespace on either side of the inline-block elements.
// Ems because we're attempting to match the width of a space character. Left
// version is for form buttons, which typically come after other elements, and
// right version is for icons, which come before. Applying both is ok, but it will
// mean that space between those elements will be .6em (~2 space characters) in IE7,
// instead of the 1 space in other browsers.
.ie7-restore-left-whitespace() {
*margin-left: .3em;
&:first-child {
*margin-left: 0;
}
}
.ie7-restore-right-whitespace() {
*margin-right: .3em;
&:last-child {
*margin-left: 0;
}
}
// Sizing shortcuts
// -------------------------
.size(@height: 5px, @width: 5px) {
width: @width;
height: @height;
}
.square(@size: 5px) {
.size(@size, @size);
}
// Placeholder text
// -------------------------
.placeholder(@color: @placeholderText) {
:-moz-placeholder {
color: @color;
}
::-webkit-input-placeholder {
color: @color;
}
}
// Text overflow
// -------------------------
// Requires inline-block or block for proper styling
.text-overflow() {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
// FONTS
// --------------------------------------------------
#font {
#family {
.serif() {
font-family: Georgia, "Times New Roman", Times, serif;
}
.sans-serif() {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
.monospace() {
font-family: Menlo, Monaco, "Courier New", monospace;
}
}
.shorthand(@size: @baseFontSize, @weight: normal, @lineHeight: @baseLineHeight) {
font-size: @size;
font-weight: @weight;
line-height: @lineHeight;
}
.serif(@size: @baseFontSize, @weight: normal, @lineHeight: @baseLineHeight) {
#font > #family > .serif;
#font > .shorthand(@size, @weight, @lineHeight);
}
.sans-serif(@size: @baseFontSize, @weight: normal, @lineHeight: @baseLineHeight) {
#font > #family > .sans-serif;
#font > .shorthand(@size, @weight, @lineHeight);
}
.monospace(@size: @baseFontSize, @weight: normal, @lineHeight: @baseLineHeight) {
#font > #family > .monospace;
#font > .shorthand(@size, @weight, @lineHeight);
}
}
// GRID SYSTEM
// --------------------------------------------------
// Site container
// -------------------------
.container-fixed() {
width: @gridRowWidth;
margin-left: auto;
margin-right: auto;
.clearfix();
}
// Le grid system
// -------------------------
#gridSystem {
// Setup the mixins to be used
.columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, @columns) {
//width: (@gridColumnWidth * @columns) + (@gridGutterWidth * (@columns - 1));
}
.offset(@gridColumnWidth, @gridGutterWidth, @columns) {
//margin-left: (@gridColumnWidth * @columns) + (@gridGutterWidth * (@columns - 1)) + (@gridGutterWidth * 2);
}
.gridColumn(@gridGutterWidth) {
float: left;
margin-left: @gridGutterWidth;
}
// Take these values and mixins, and make 'em do their thang
.generate(@gridColumns, @gridColumnWidth, @gridGutterWidth) {
// Row surrounds the columns
.row {
//margin-left: @gridGutterWidth * -1;
.clearfix();
}
// Find all .span# classes within .row and give them the necessary properties for grid columns (supported by all browsers back to IE7, thanks @dhg)
[class*="span"] {
#gridSystem > .gridColumn(@gridGutterWidth);
}
// Default columns
.span1 { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 1); }
.span2 { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 2); }
.span3 { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 3); }
.span4 { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 4); }
.span5 { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 5); }
.span6 { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 6); }
.span7 { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 7); }
.span8 { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 8); }
.span9 { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 9); }
.span10 { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 10); }
.span11 { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 11); }
.span12,
.container { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 12); }
// Offset column options
.offset1 { #gridSystem > .offset(@gridColumnWidth, @gridGutterWidth, 1); }
.offset2 { #gridSystem > .offset(@gridColumnWidth, @gridGutterWidth, 2); }
.offset3 { #gridSystem > .offset(@gridColumnWidth, @gridGutterWidth, 3); }
.offset4 { #gridSystem > .offset(@gridColumnWidth, @gridGutterWidth, 4); }
.offset5 { #gridSystem > .offset(@gridColumnWidth, @gridGutterWidth, 5); }
.offset6 { #gridSystem > .offset(@gridColumnWidth, @gridGutterWidth, 6); }
.offset7 { #gridSystem > .offset(@gridColumnWidth, @gridGutterWidth, 7); }
.offset8 { #gridSystem > .offset(@gridColumnWidth, @gridGutterWidth, 8); }
.offset9 { #gridSystem > .offset(@gridColumnWidth, @gridGutterWidth, 9); }
.offset10 { #gridSystem > .offset(@gridColumnWidth, @gridGutterWidth, 10); }
.offset11 { #gridSystem > .offset(@gridColumnWidth, @gridGutterWidth, 11); }
}
}
// Fluid grid system
// -------------------------
#fluidGridSystem {
// Setup the mixins to be used
.columns(@fluidGridGutterWidth, @fluidGridColumnWidth, @columns) {
//width: 1% * (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1));
}
.gridColumn(@fluidGridGutterWidth) {
float: left;
margin-left: @fluidGridGutterWidth;
}
// Take these values and mixins, and make 'em do their thang
.generate(@gridColumns, @fluidGridColumnWidth, @fluidGridGutterWidth) {
// Row surrounds the columns
.row-fluid {
width: 100%;
.clearfix();
// Find all .span# classes within .row and give them the necessary properties for grid columns (supported by all browsers back to IE7, thanks @dhg)
> [class*="span"] {
#fluidGridSystem > .gridColumn(@fluidGridGutterWidth);
}
> [class*="span"]:first-child {
margin-left: 0;
}
// Default columns
> .span1 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 1); }
> .span2 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 2); }
> .span3 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 3); }
> .span4 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 4); }
> .span5 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 5); }
> .span6 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 6); }
> .span7 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 7); }
> .span8 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 8); }
> .span9 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 9); }
> .span10 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 10); }
> .span11 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 11); }
> .span12 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 12); }
}
}
}
// Input grid system
// -------------------------
#inputGridSystem {
.inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, @columns) {
//width: ((@gridColumnWidth) * @columns) + (@gridGutterWidth * (@columns - 1)) - 10;
}
.generate(@gridColumns, @gridColumnWidth, @gridGutterWidth) {
input,
textarea,
.uneditable-input {
&.span1 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 1); }
&.span2 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 2); }
&.span3 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 3); }
&.span4 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 4); }
&.span5 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 5); }
&.span6 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 6); }
&.span7 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 7); }
&.span8 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 8); }
&.span9 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 9); }
&.span10 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 10); }
&.span11 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 11); }
&.span12 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 12); }
}
}
}
// Make a Grid
// -------------------------
// Use .makeRow and .makeColumn to assign semantic layouts grid system behavior
.makeRow() {
//margin-left: @gridGutterWidth * -1;
.clearfix();
}
.makeColumn(@columns: 1) {
float: left;
margin-left: @gridGutterWidth;
//width: (@gridColumnWidth * @columns) + (@gridGutterWidth * (@columns - 1));
}
// Form field states (used in forms.less)
// --------------------------------------------------
// Mixin for form field states
.formFieldState(@textColor: #555, @borderColor: #ccc, @backgroundColor: #f5f5f5) {
// Set the text color
> label,
.help-block,
.help-inline {
color: @textColor;
}
// Style inputs accordingly
input,
select,
textarea {
color: @textColor;
border-color: @borderColor;
&:focus {
border-color: darken(@borderColor, 10%);
.box-shadow(0 0 6px lighten(@borderColor, 20%));
}
}
// Give a small background color for input-prepend/-append
.input-prepend .add-on,
.input-append .add-on {
color: @textColor;
background-color: @backgroundColor;
border-color: @textColor;
}
}
// CSS3 PROPERTIES
// --------------------------------------------------
// Border Radius
.border-radius(@radius: 5px) {
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
border-radius: @radius;
}
// Drop shadows
.box-shadow(@shadow: 0 1px 3px rgba(0,0,0,.25)) {
-webkit-box-shadow: @shadow;
-moz-box-shadow: @shadow;
box-shadow: @shadow;
}
// Transitions
.transition(@transition) {
-webkit-transition: @transition;
-moz-transition: @transition;
-ms-transition: @transition;
-o-transition: @transition;
transition: @transition;
}
// Transformations
.rotate(@degrees) {
-webkit-transform: rotate(@degrees);
-moz-transform: rotate(@degrees);
-ms-transform: rotate(@degrees);
-o-transform: rotate(@degrees);
transform: rotate(@degrees);
}
.scale(@ratio) {
-webkit-transform: scale(@ratio);
-moz-transform: scale(@ratio);
-ms-transform: scale(@ratio);
-o-transform: scale(@ratio);
transform: scale(@ratio);
}
.translate(@x: 0, @y: 0) {
-webkit-transform: translate(@x, @y);
-moz-transform: translate(@x, @y);
-ms-transform: translate(@x, @y);
-o-transform: translate(@x, @y);
transform: translate(@x, @y);
}
.skew(@x: 0, @y: 0) {
-webkit-transform: skew(@x, @y);
-moz-transform: skew(@x, @y);
-ms-transform: skew(@x, @y);
-o-transform: skew(@x, @y);
transform: skew(@x, @y);
}
.translate3d(@x: 0, @y: 0, @z: 0) {
-webkit-transform: translate(@x, @y, @z);
-moz-transform: translate(@x, @y, @z);
-ms-transform: translate(@x, @y, @z);
-o-transform: translate(@x, @y, @z);
transform: translate(@x, @y, @z);
}
// Background clipping
// Heads up: FF 3.6 and under need "padding" instead of "padding-box"
.background-clip(@clip) {
-webkit-background-clip: @clip;
-moz-background-clip: @clip;
background-clip: @clip;
}
// Background sizing
.background-size(@size){
-webkit-background-size: @size;
-moz-background-size: @size;
-o-background-size: @size;
background-size: @size;
}
// Box sizing
.box-sizing(@boxmodel) {
-webkit-box-sizing: @boxmodel;
-moz-box-sizing: @boxmodel;
box-sizing: @boxmodel;
}
// User select
// For selecting text on the page
.user-select(@select) {
-webkit-user-select: @select;
-moz-user-select: @select;
-o-user-select: @select;
user-select: @select;
}
// Resize anything
.resizable(@direction: both) {
resize: @direction; // Options: horizontal, vertical, both
overflow: auto; // Safari fix
}
// CSS3 Content Columns
.content-columns(@columnCount, @columnGap: @gridColumnGutter) {
-webkit-column-count: @columnCount;
-moz-column-count: @columnCount;
column-count: @columnCount;
-webkit-column-gap: @columnGap;
-moz-column-gap: @columnGap;
column-gap: @columnGap;
}
// Opacity
.opacity(@opacity: 100) {
//opacity: @opacity / 100;
filter: e(%("alpha(opacity=%d)", @opacity));
}
// BACKGROUNDS
// --------------------------------------------------
// Add an alphatransparency value to any background or border color (via Elyse Holladay)
#translucent {
.background(@color: @white, @alpha: 1) {
background-color: hsla(hue(@color), saturation(@color), lightness(@color), @alpha);
}
.border(@color: @white, @alpha: 1) {
border-color: hsla(hue(@color), saturation(@color), lightness(@color), @alpha);
.background-clip(padding-box);
}
}
// Gradient Bar Colors for buttons and alerts
.gradientBar(@primaryColor, @secondaryColor) {
#gradient > .vertical(@primaryColor, @secondaryColor);
border-color: @secondaryColor @secondaryColor darken(@secondaryColor, 15%);
border-color: rgba(0,0,0,.1) rgba(0,0,0,.1) fadein(rgba(0,0,0,.1), 15%);
}
// Gradients
#gradient {
.horizontal(@startColor: #555, @endColor: #333) {
background-color: @endColor;
background-image: -moz-linear-gradient(left, @startColor, @endColor); // FF 3.6+
background-image: -ms-linear-gradient(left, @startColor, @endColor); // IE10
background-image: -webkit-gradient(linear, 0 0, 100% 0, from(@startColor), to(@endColor)); // Safari 4+, Chrome 2+
background-image: -webkit-linear-gradient(left, @startColor, @endColor); // Safari 5.1+, Chrome 10+
background-image: -o-linear-gradient(left, @startColor, @endColor); // Opera 11.10
background-image: linear-gradient(left, @startColor, @endColor); // Le standard
background-repeat: repeat-x;
filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)",@startColor,@endColor)); // IE9 and down
}
.vertical(@startColor: #555, @endColor: #333) {
background-color: mix(@startColor, @endColor, 60%);
background-image: -moz-linear-gradient(top, @startColor, @endColor); // FF 3.6+
background-image: -ms-linear-gradient(top, @startColor, @endColor); // IE10
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(@startColor), to(@endColor)); // Safari 4+, Chrome 2+
background-image: -webkit-linear-gradient(top, @startColor, @endColor); // Safari 5.1+, Chrome 10+
background-image: -o-linear-gradient(top, @startColor, @endColor); // Opera 11.10
background-image: linear-gradient(top, @startColor, @endColor); // The standard
background-repeat: repeat-x;
filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",@startColor,@endColor)); // IE9 and down
}
.directional(@startColor: #555, @endColor: #333, @deg: 45deg) {
background-color: @endColor;
background-repeat: repeat-x;
background-image: -moz-linear-gradient(@deg, @startColor, @endColor); // FF 3.6+
background-image: -ms-linear-gradient(@deg, @startColor, @endColor); // IE10
background-image: -webkit-linear-gradient(@deg, @startColor, @endColor); // Safari 5.1+, Chrome 10+
background-image: -o-linear-gradient(@deg, @startColor, @endColor); // Opera 11.10
background-image: linear-gradient(@deg, @startColor, @endColor); // The standard
}
.vertical-three-colors(@startColor: #00b3ee, @midColor: #7a43b6, @colorStop: 50%, @endColor: #c3325f) {
background-color: mix(@midColor, @endColor, 80%);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(@startColor), color-stop(@colorStop, @midColor), to(@endColor));
background-image: -webkit-linear-gradient(@startColor, @midColor @colorStop, @endColor);
background-image: -moz-linear-gradient(top, @startColor, @midColor @colorStop, @endColor);
background-image: -ms-linear-gradient(@startColor, @midColor @colorStop, @endColor);
background-image: -o-linear-gradient(@startColor, @midColor @colorStop, @endColor);
background-image: linear-gradient(@startColor, @midColor @colorStop, @endColor);
background-repeat: no-repeat;
filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",@startColor,@endColor)); // IE9 and down, gets no color-stop at all for proper fallback
}
.radial(@innerColor: #555, @outerColor: #333) {
background-color: @outerColor;
background-image: -webkit-gradient(radial, center center, 0, center center, 460, from(@innerColor), to(@outerColor));
background-image: -webkit-radial-gradient(circle, @innerColor, @outerColor);
background-image: -moz-radial-gradient(circle, @innerColor, @outerColor);
background-image: -ms-radial-gradient(circle, @innerColor, @outerColor);
background-repeat: no-repeat;
// Opera cannot do radial gradients yet
}
.striped(@color, @angle: -45deg) {
background-color: @color;
background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, rgba(255,255,255,.15)), color-stop(.25, transparent), color-stop(.5, transparent), color-stop(.5, rgba(255,255,255,.15)), color-stop(.75, rgba(255,255,255,.15)), color-stop(.75, transparent), to(transparent));
background-image: -webkit-linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent);
background-image: -moz-linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent);
background-image: -ms-linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent);
background-image: -o-linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent);
background-image: linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent);
}
}
// Reset filters for IE
.reset-filter() {
filter: e(%("progid:DXImageTransform.Microsoft.gradient(enabled = false)"));
}
// Mixin for generating button backgrounds
// ---------------------------------------
.buttonBackground(@startColor, @endColor) {
// gradientBar will set the background to a pleasing blend of these, to support IE<=9
.gradientBar(@startColor, @endColor);
.reset-filter();
// in these cases the gradient won't cover the background, so we override
&:hover, &:active, &.active, &.disabled, &[disabled] {
background-color: @endColor;
}
// IE 7 + 8 can't handle box-shadow to show active, so we darken a bit ourselves
&:active,
&.active {
background-color: darken(@endColor, 10%) e("\9");
}
}
// COMPONENT MIXINS
// --------------------------------------------------
// POPOVER ARROWS
// -------------------------
// For tipsies and popovers
#popoverArrow {
.top(@arrowWidth: 5px) {
bottom: 0;
left: 50%;
margin-left: -@arrowWidth;
border-left: @arrowWidth solid transparent;
border-right: @arrowWidth solid transparent;
border-top: @arrowWidth solid @black;
}
.left(@arrowWidth: 5px) {
top: 50%;
right: 0;
margin-top: -@arrowWidth;
border-top: @arrowWidth solid transparent;
border-bottom: @arrowWidth solid transparent;
border-left: @arrowWidth solid @black;
}
.bottom(@arrowWidth: 5px) {
top: 0;
left: 50%;
margin-left: -@arrowWidth;
border-left: @arrowWidth solid transparent;
border-right: @arrowWidth solid transparent;
border-bottom: @arrowWidth solid @black;
}
.right(@arrowWidth: 5px) {
top: 50%;
left: 0;
margin-top: -@arrowWidth;
border-top: @arrowWidth solid transparent;
border-bottom: @arrowWidth solid transparent;
border-right: @arrowWidth solid @black;
}
}

View file

@ -0,0 +1,87 @@
// MODALS
// ------
// Recalculate z-index where appropriate
.modal-open {
.dropdown-menu { z-index: (@zindexDropdown + @zindexModal); }
.dropdown.open { *z-index: (@zindexDropdown + @zindexModal); }
.popover { z-index: (@zindexPopover + @zindexModal); }
.tooltip { z-index: (@zindexTooltip + @zindexModal); }
}
.modal-body a {
color: #0AAADF;
}
// Background
.modal-backdrop {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: @zindexModalBackdrop;
background-color: @black;
// Fade for backdrop
&.fade { opacity: 0; }
}
.modal-backdrop,
.modal-backdrop.fade.in {
opacity: 0.6;
}
// Base modal
.modal {
position: fixed;
top: 50%;
left: 50%;
z-index: @zindexModal;
max-height: 580px;
overflow: auto;
width: 560px;
margin: -250px 0 0 -280px;
background-color: @white;
border: 1px solid #999;
border: 1px solid rgba(0,0,0,.3);
*border: 1px solid #999; /* IE6-7 */
.border-radius(6px);
.box-shadow(0 3px 7px rgba(0,0,0,0.3));
.background-clip(padding-box);
&.fade {
.transition(e('opacity .3s linear, top .3s ease-out'));
top: -25%;
}
&.fade.in { top: 50%; }
}
.modal-header {
padding: 9px 15px;
border-bottom: 1px solid #eee;
// Close icon
.close { margin-top: 2px; }
}
// Body (where all modal content resises)
.modal-body {
padding: 15px;
}
// Remove bottom margin if need be
.modal-body .modal-form {
margin-bottom: 0;
}
// Footer (for actions)
.modal-footer {
padding: 14px 15px 15px;
margin-bottom: 0;
background-color: #f5f5f5;
border-top: 1px solid #ddd;
.border-radius(0 0 6px 6px);
.box-shadow(inset 0 1px 0 @white);
.clearfix();
.btn {
float: right;
margin-left: 5px;
margin-bottom: 0; // account for input[type="submit"] which gets the bottom margin like all other inputs
}
}

View file

@ -0,0 +1,299 @@
// NAVBAR (FIXED AND STATIC)
// -------------------------
// COMMON STYLES
// -------------
.navbar {
overflow: visible;
margin-bottom: @baseLineHeight;
}
// Gradient is applied to it's own element because overflow visible is not honored by IE when filter is present
.navbar-inner {
padding-left: 20px;
padding-right: 20px;
#gradient > .vertical(@navbarBackgroundHighlight, @navbarBackground);
.border-radius(4px);
@shadow: 0 1px 3px rgba(0,0,0,.25), inset 0 -1px 0 rgba(0,0,0,.1);
.box-shadow(@shadow);
}
// Navbar button for toggling navbar items in responsive layouts
.btn-navbar {
display: none;
float: right;
padding: 7px 10px;
margin-left: 5px;
margin-right: 5px;
.buttonBackground(@navbarBackgroundHighlight, @navbarBackground);
@shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075);
.box-shadow(@shadow);
}
.btn-navbar .icon-bar {
display: block;
width: 18px;
height: 2px;
background-color: #f5f5f5;
.border-radius(1px);
.box-shadow(0 1px 0 rgba(0,0,0,.25));
}
.btn-navbar .icon-bar + .icon-bar {
margin-top: 3px;
}
// Override the default collapsed state
.nav-collapse.collapse {
height: auto;
}
// Brand, links, text, and buttons
.navbar {
// Hover and active states
.brand:hover {
text-decoration: none;
}
// Website or project name
.brand {
float: left;
display: block;
padding: 8px 20px 12px;
margin-left: -20px; // negative indent to left-align the text down the page
font-size: 20px;
font-weight: 200;
line-height: 1;
color: @white;
}
// Plain text in topbar
.navbar-text {
margin-bottom: 0;
line-height: 40px;
color: @navbarText;
a:hover {
color: @white;
background-color: transparent;
}
}
// Buttons in navbar
.btn,
.btn-group {
margin-top: 5px; // make buttons vertically centered in navbar
}
.btn-group .btn {
margin-top: 0; // then undo the margin here so we don't accidentally double it
}
}
// Navbar forms
.navbar-form {
margin-bottom: 0; // remove default bottom margin
.clearfix();
input,
select {
display: inline-block;
margin-top: 5px;
margin-bottom: 0;
}
.radio,
.checkbox {
margin-top: 5px;
}
input[type="image"],
input[type="checkbox"],
input[type="radio"] {
margin-top: 3px;
}
.input-append,
.input-prepend {
margin-top: 6px;
white-space: nowrap; // preven two items from separating within a .navbar-form that has .pull-left
input {
margin-top: 0; // remove the margin on top since it's on the parent
}
}
}
// Navbar search
.navbar-search {
position: relative;
float: left;
margin-top: 6px;
margin-bottom: 0;
.search-query {
padding: 4px 9px;
#font > .sans-serif(13px, normal, 1);
color: @white;
color: rgba(255,255,255,.75);
background: #666;
background: rgba(255,255,255,.3);
border: 1px solid #111;
@shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0px rgba(255,255,255,.15);
.box-shadow(@shadow);
.transition(none);
// Placeholder text gets special styles; can't be bundled together though for some reason
.placeholder(@grayLighter);
// Hover states
&:hover {
color: @white;
background-color: @grayLight;
background-color: rgba(255,255,255,.5);
}
// Focus states (we use .focused since IE7-8 and down doesn't support :focus)
&:focus,
&.focused {
padding: 5px 10px;
color: @grayDark;
text-shadow: 0 1px 0 @white;
background-color: @white;
border: 0;
.box-shadow(0 0 3px rgba(0,0,0,.15));
outline: 0;
}
}
}
// FIXED NAVBAR
// ------------
.navbar-fixed-top {
position: fixed;
top: 0;
right: 0;
left: 0;
z-index: @zindexFixedNavbar;
}
.navbar-fixed-top .navbar-inner {
padding-left: 0;
padding-right: 0;
.border-radius(0);
}
// NAVIGATION
// ----------
.navbar .nav {
position: relative;
left: 0;
display: block;
float: left;
margin: 0 10px 0 0;
}
.navbar .nav.pull-right {
float: right; // redeclare due to specificity
}
.navbar .nav > li {
display: block;
float: left;
}
// Links
.navbar .nav > li > a {
float: none;
padding: 10px 10px 11px;
line-height: 19px;
color: @navbarLinkColor;
text-decoration: none;
text-shadow: 0 -1px 0 rgba(0,0,0,.25);
}
// Hover
.navbar .nav > li > a:hover {
background-color: @navbarLinkBackgroundHover; // "transparent" is default to differentiate :hover from .active
color: @navbarLinkColorHover;
text-decoration: none;
}
// Active nav items
.navbar .nav .active > a,
.navbar .nav .active > a:hover {
color: @navbarLinkColorHover;
text-decoration: none;
background-color: @navbarBackground;
}
// Dividers (basically a vertical hr)
.navbar .divider-vertical {
height: @navbarHeight;
width: 1px;
margin: 0 9px;
overflow: hidden;
background-color: @navbarBackground;
border-right: 1px solid @navbarBackgroundHighlight;
}
// Secondary (floated right) nav in topbar
.navbar .nav.pull-right {
margin-left: 10px;
margin-right: 0;
}
// Dropdown menus
// --------------
// Menu position and menu carets
.navbar .dropdown-menu {
margin-top: 1px;
.border-radius(4px);
&:before {
content: '';
display: inline-block;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-bottom: 7px solid #ccc;
border-bottom-color: rgba(0,0,0,.2);
position: absolute;
top: -7px;
left: 9px;
}
&:after {
content: '';
display: inline-block;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid @white;
position: absolute;
top: -6px;
left: 10px;
}
}
// Dropdown toggle caret
.navbar .nav .dropdown-toggle .caret,
.navbar .nav .open.dropdown .caret {
border-top-color: @white;
}
.navbar .nav .active .caret {
.opacity(100);
}
// Remove background color from open dropdown
.navbar .nav .open > .dropdown-toggle,
.navbar .nav .active > .dropdown-toggle,
.navbar .nav .open.active > .dropdown-toggle {
background-color: transparent;
}
// Dropdown link on hover
.navbar .nav .active > .dropdown-toggle:hover {
color: @white;
}
// Right aligned menus need alt position
.navbar .nav.pull-right .dropdown-menu {
left: auto;
right: 0;
&:before {
left: auto;
right: 12px;
}
&:after {
left: auto;
right: 13px;
}
}

View file

@ -0,0 +1,353 @@
// NAVIGATIONS
// -----------
// BASE CLASS
// ----------
.nav {
margin-left: 0;
margin-bottom: @baseLineHeight;
list-style: none;
}
// Make links block level
.nav > li > a {
display: block;
}
.nav > li > a:hover {
text-decoration: none;
background-color: @grayLighter;
}
// Nav headers (for dropdowns and lists)
.nav .nav-header {
display: block;
padding: 3px 15px;
font-size: 11px;
font-weight: bold;
line-height: @baseLineHeight;
color: @grayLight;
text-shadow: 0 1px 0 rgba(255,255,255,.5);
text-transform: uppercase;
}
// Space them out when they follow another list item (link)
.nav li + .nav-header {
margin-top: 9px;
}
// NAV LIST
// --------
.nav-list {
padding-left: 14px;
padding-right: 14px;
margin-bottom: 0;
}
.nav-list > li > a,
.nav-list .nav-header {
margin-left: -15px;
margin-right: -15px;
text-shadow: 0 1px 0 rgba(255,255,255,.5);
}
.nav-list > li > a {
padding: 3px 15px;
}
.nav-list .active > a,
.nav-list .active > a:hover {
color: @white;
text-shadow: 0 -1px 0 rgba(0,0,0,.2);
background-color: @linkColor;
}
.nav-list [class^="icon-"] {
margin-right: 2px;
}
// TABS AND PILLS
// -------------
// Common styles
.nav-tabs,
.nav-pills {
.clearfix();
}
.nav-tabs > li,
.nav-pills > li {
float: left;
}
.nav-tabs > li > a,
.nav-pills > li > a {
padding-right: 12px;
padding-left: 12px;
margin-right: 2px;
line-height: 14px; // keeps the overall height an even number
}
// TABS
// ----
// Give the tabs something to sit on
.nav-tabs {
border-bottom: 1px solid #ddd;
}
// Make the list-items overlay the bottom border
.nav-tabs > li {
margin-bottom: -1px;
}
// Actual tabs (as links)
.nav-tabs > li > a {
padding-top: 9px;
padding-bottom: 9px;
border: 1px solid transparent;
.border-radius(4px 4px 0 0);
&:hover {
border-color: @grayLighter @grayLighter #ddd;
}
}
// Active state, and it's :hover to override normal :hover
.nav-tabs > .active > a,
.nav-tabs > .active > a:hover {
color: @gray;
background-color: @white;
border: 1px solid #ddd;
border-bottom-color: transparent;
cursor: default;
}
// PILLS
// -----
// Links rendered as pills
.nav-pills > li > a {
padding-top: 8px;
padding-bottom: 8px;
margin-top: 2px;
margin-bottom: 2px;
.border-radius(5px);
}
// Active state
.nav-pills .active > a,
.nav-pills .active > a:hover {
color: @white;
background-color: @linkColor;
}
// STACKED NAV
// -----------
// Stacked tabs and pills
.nav-stacked > li {
float: none;
}
.nav-stacked > li > a {
margin-right: 0; // no need for the gap between nav items
}
// Tabs
.nav-tabs.nav-stacked {
border-bottom: 0;
}
.nav-tabs.nav-stacked > li > a {
border: 1px solid #ddd;
.border-radius(0);
}
.nav-tabs.nav-stacked > li:first-child > a {
.border-radius(4px 4px 0 0);
}
.nav-tabs.nav-stacked > li:last-child > a {
.border-radius(0 0 4px 4px);
}
.nav-tabs.nav-stacked > li > a:hover {
border-color: #ddd;
z-index: 2;
}
// Pills
.nav-pills.nav-stacked > li > a {
margin-bottom: 3px;
}
.nav-pills.nav-stacked > li:last-child > a {
margin-bottom: 1px; // decrease margin to match sizing of stacked tabs
}
// DROPDOWNS
// ---------
// Position the menu
.nav-tabs .dropdown-menu,
.nav-pills .dropdown-menu {
margin-top: 1px;
border-width: 1px;
}
.nav-pills .dropdown-menu {
.border-radius(4px);
}
// Default dropdown links
// -------------------------
// Make carets use linkColor to start
.nav-tabs .dropdown-toggle .caret,
.nav-pills .dropdown-toggle .caret {
border-top-color: @linkColor;
margin-top: 6px;
}
.nav-tabs .dropdown-toggle:hover .caret,
.nav-pills .dropdown-toggle:hover .caret {
border-top-color: @linkColorHover;
}
// Active dropdown links
// -------------------------
.nav-tabs .active .dropdown-toggle .caret,
.nav-pills .active .dropdown-toggle .caret {
border-top-color: @grayDark;
}
// Active:hover dropdown links
// -------------------------
.nav > .dropdown.active > a:hover {
color: @black;
cursor: pointer;
}
// Open dropdowns
// -------------------------
.nav-tabs .open .dropdown-toggle,
.nav-pills .open .dropdown-toggle,
.nav > .open.active > a:hover {
color: @white;
background-color: @grayLight;
border-color: @grayLight;
}
.nav .open .caret,
.nav .open.active .caret,
.nav .open a:hover .caret {
border-top-color: @white;
.opacity(100);
}
// Dropdowns in stacked tabs
.tabs-stacked .open > a:hover {
border-color: @grayLight;
}
// TABBABLE
// --------
// COMMON STYLES
// -------------
// Clear any floats
.tabbable {
.clearfix();
}
.tab-content {
overflow: hidden; // prevent content from running below tabs
}
// Remove border on bottom, left, right
.tabs-below .nav-tabs,
.tabs-right .nav-tabs,
.tabs-left .nav-tabs {
border-bottom: 0;
}
// Show/hide tabbable areas
.tab-content > .tab-pane,
.pill-content > .pill-pane {
display: none;
}
.tab-content > .active,
.pill-content > .active {
display: block;
}
// BOTTOM
// ------
.tabs-below .nav-tabs {
border-top: 1px solid #ddd;
}
.tabs-below .nav-tabs > li {
margin-top: -1px;
margin-bottom: 0;
}
.tabs-below .nav-tabs > li > a {
.border-radius(0 0 4px 4px);
&:hover {
border-bottom-color: transparent;
border-top-color: #ddd;
}
}
.tabs-below .nav-tabs .active > a,
.tabs-below .nav-tabs .active > a:hover {
border-color: transparent #ddd #ddd #ddd;
}
// LEFT & RIGHT
// ------------
// Common styles
.tabs-left .nav-tabs > li,
.tabs-right .nav-tabs > li {
float: none;
}
.tabs-left .nav-tabs > li > a,
.tabs-right .nav-tabs > li > a {
min-width: 74px;
margin-right: 0;
margin-bottom: 3px;
}
// Tabs on the left
.tabs-left .nav-tabs {
float: left;
margin-right: 19px;
border-right: 1px solid #ddd;
}
.tabs-left .nav-tabs > li > a {
margin-right: -1px;
.border-radius(4px 0 0 4px);
}
.tabs-left .nav-tabs > li > a:hover {
border-color: @grayLighter #ddd @grayLighter @grayLighter;
}
.tabs-left .nav-tabs .active > a,
.tabs-left .nav-tabs .active > a:hover {
border-color: #ddd transparent #ddd #ddd;
*border-right-color: @white;
}
// Tabs on the right
.tabs-right .nav-tabs {
float: right;
margin-left: 19px;
border-left: 1px solid #ddd;
}
.tabs-right .nav-tabs > li > a {
margin-left: -1px;
.border-radius(0 4px 4px 0);
}
.tabs-right .nav-tabs > li > a:hover {
border-color: @grayLighter @grayLighter @grayLighter #ddd;
}
.tabs-right .nav-tabs .active > a,
.tabs-right .nav-tabs .active > a:hover {
border-color: #ddd #ddd #ddd transparent;
*border-left-color: @white;
}

View file

@ -0,0 +1,30 @@
// PAGER
// -----
.pager {
margin-left: 0;
margin-bottom: @baseLineHeight;
list-style: none;
text-align: center;
.clearfix();
}
.pager li {
display: inline;
}
.pager a {
display: inline-block;
padding: 5px 14px;
background-color: #fff;
border: 1px solid #ddd;
.border-radius(15px);
}
.pager a:hover {
text-decoration: none;
background-color: #f5f5f5;
}
.pager .next a {
float: right;
}
.pager .previous a {
float: left;
}

View file

@ -0,0 +1,55 @@
// PAGINATION
// ----------
.pagination {
//height: @baseLineHeight * 2;
margin: @baseLineHeight 0;
}
.pagination ul {
display: inline-block;
.ie7-inline-block();
margin-left: 0;
margin-bottom: 0;
.border-radius(3px);
.box-shadow(0 1px 2px rgba(0,0,0,.05));
}
.pagination li {
display: inline;
}
.pagination a {
float: left;
padding: 0 14px;
//line-height: (@baseLineHeight * 2) - 2;
text-decoration: none;
border: 1px solid #ddd;
border-left-width: 0;
}
.pagination a:hover,
.pagination .active a {
background-color: #f5f5f5;
}
.pagination .active a {
color: @grayLight;
cursor: default;
}
.pagination .disabled a,
.pagination .disabled a:hover {
color: @grayLight;
background-color: transparent;
cursor: default;
}
.pagination li:first-child a {
border-left-width: 1px;
.border-radius(3px 0 0 3px);
}
.pagination li:last-child a {
.border-radius(0 3px 3px 0);
}
// Centered
.pagination-centered {
text-align: center;
}
.pagination-right {
text-align: right;
}

View file

@ -0,0 +1,49 @@
// POPOVERS
// --------
.popover {
position: absolute;
top: 0;
left: 0;
z-index: @zindexPopover;
display: none;
padding: 5px;
&.top { margin-top: -5px; }
&.right { margin-left: 5px; }
&.bottom { margin-top: 5px; }
&.left { margin-left: -5px; }
&.top .arrow { #popoverArrow > .top(); }
&.right .arrow { #popoverArrow > .right(); }
&.bottom .arrow { #popoverArrow > .bottom(); }
&.left .arrow { #popoverArrow > .left(); }
.arrow {
position: absolute;
width: 0;
height: 0;
}
}
.popover-inner {
padding: 3px;
width: 280px;
overflow: hidden;
background: @black; // has to be full background declaration for IE fallback
background: rgba(0,0,0,.8);
.border-radius(6px);
.box-shadow(0 3px 7px rgba(0,0,0,0.3));
}
.popover-title {
padding: 9px 15px;
line-height: 1;
background-color: #f5f5f5;
border-bottom:1px solid #eee;
.border-radius(3px 3px 0 0);
}
.popover-content {
padding: 14px;
background-color: @white;
.border-radius(0 0 3px 3px);
.background-clip(padding-box);
p, ul, ol {
margin-bottom: 0;
}
}

View file

@ -0,0 +1,95 @@
// PROGRESS BARS
// -------------
// ANIMATIONS
// ----------
// Webkit
@-webkit-keyframes progress-bar-stripes {
from { background-position: 0 0; }
to { background-position: 40px 0; }
}
// Firefox
@-moz-keyframes progress-bar-stripes {
from { background-position: 0 0; }
to { background-position: 40px 0; }
}
// Spec
@keyframes progress-bar-stripes {
from { background-position: 0 0; }
to { background-position: 40px 0; }
}
// THE BARS
// --------
// Outer container
.progress {
overflow: hidden;
height: 18px;
margin-bottom: 18px;
#gradient > .vertical(#f5f5f5, #f9f9f9);
.box-shadow(inset 0 1px 2px rgba(0,0,0,.1));
.border-radius(4px);
}
// Bar of progress
.progress .bar {
width: 0%;
height: 18px;
color: @white;
font-size: 12px;
text-align: center;
text-shadow: 0 -1px 0 rgba(0,0,0,.25);
#gradient > .vertical(#149bdf, #0480be);
.box-shadow(inset 0 -1px 0 rgba(0,0,0,.15));
.box-sizing(border-box);
.transition(width .6s ease);
}
// Striped bars
.progress-striped .bar {
#gradient > .striped(#62c462);
.background-size(40px 40px);
}
// Call animation for the active one
.progress.active .bar {
-webkit-animation: progress-bar-stripes 2s linear infinite;
-moz-animation: progress-bar-stripes 2s linear infinite;
animation: progress-bar-stripes 2s linear infinite;
}
// COLORS
// ------
// Danger (red)
.progress-danger .bar {
#gradient > .vertical(#ee5f5b, #c43c35);
}
.progress-danger.progress-striped .bar {
#gradient > .striped(#ee5f5b);
}
// Success (green)
.progress-success .bar {
#gradient > .vertical(#62c462, #57a957);
}
.progress-success.progress-striped .bar {
#gradient > .striped(#62c462);
}
// Info (teal)
.progress-info .bar {
#gradient > .vertical(#5bc0de, #339bb9);
}
.progress-info.progress-striped .bar {
#gradient > .striped(#5bc0de);
}

View file

@ -0,0 +1,126 @@
// Reset.less
// Adapted from Normalize.css http://github.com/necolas/normalize.css
// ------------------------------------------------------------------------
// Display in IE6-9 and FF3
// -------------------------
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
nav,
section {
display: block;
}
// Display block in IE6-9 and FF3
// -------------------------
audio,
canvas,
video {
display: inline-block;
*display: inline;
*zoom: 1;
}
// Prevents modern browsers from displaying 'audio' without controls
// -------------------------
audio:not([controls]) {
display: none;
}
// Base settings
// -------------------------
html {
font-size: 100%;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
// Focus states
a:focus {
.tab-focus();
}
// Hover & Active
a:hover,
a:active {
outline: 0;
}
// Prevents sub and sup affecting line-height in all browsers
// -------------------------
sub,
sup {
position: relative;
font-size: 75%;
line-height: 0;
vertical-align: baseline;
}
sup {
top: -0.5em;
}
sub {
bottom: -0.25em;
}
// Img border in a's and image quality
// -------------------------
img {
max-width: 100%;
height: auto;
border: 0;
-ms-interpolation-mode: bicubic;
}
// Forms
// -------------------------
// Font size in all browsers, margin changes, misc consistency
button,
input,
select,
textarea {
margin: 0;
font-size: 100%;
vertical-align: middle;
}
button,
input {
*overflow: visible; // Inner spacing ie IE6/7
line-height: normal; // FF3/4 have !important on line-height in UA stylesheet
}
button::-moz-focus-inner,
input::-moz-focus-inner { // Inner padding and border oddities in FF3/4
padding: 0;
border: 0;
}
button,
input[type="button"],
input[type="reset"],
input[type="submit"] {
cursor: pointer; // Cursors on all buttons applied consistently
-webkit-appearance: button; // Style clickable inputs in iOS
}
input[type="search"] { // Appearance in Safari/Chrome
-webkit-appearance: textfield;
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
}
input[type="search"]::-webkit-search-decoration,
input[type="search"]::-webkit-search-cancel-button {
-webkit-appearance: none; // Inner-padding issues in Chrome OSX, Safari 5
}
textarea {
overflow: auto; // Remove vertical scrollbar in IE6-9
vertical-align: top; // Readability and alignment cross-browser
}

View file

@ -0,0 +1,327 @@
/*!
* Bootstrap Responsive v2.0.1
*
* Copyright 2012 Twitter, Inc
* Licensed under the Apache License v2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Designed and built with all the love in the world @twitter by @mdo and @fat.
*/
// Responsive.less
// For phone and tablet devices
// -------------------------------------------------------------
// REPEAT VARIABLES & MIXINS
// -------------------------
// Required since we compile the responsive stuff separately
@import "variables.less"; // Modify this for custom colors, font-sizes, etc
@import "mixins.less";
// RESPONSIVE CLASSES
// ------------------
// Hide from screenreaders and browsers
// Credit: HTML5 Boilerplate
.hidden {
display: none;
visibility: hidden;
}
// UP TO LANDSCAPE PHONE
// ---------------------
@media (max-width: 480px) {
// Smooth out the collapsing/expanding nav
.nav-collapse {
-webkit-transform: translate3d(0, 0, 0); // activate the GPU
}
// Block level the page header small tag for readability
.page-header h1 small {
display: block;
line-height: @baseLineHeight;
}
// Make span* classes full width
input[class*="span"],
select[class*="span"],
textarea[class*="span"],
.uneditable-input {
display: block;
width: 100%;
min-height: 28px; /* Make inputs at least the height of their button counterpart */
/* Makes inputs behave like true block-level elements */
-webkit-box-sizing: border-box; /* Older Webkit */
-moz-box-sizing: border-box; /* Older FF */
-ms-box-sizing: border-box; /* IE8 */
box-sizing: border-box; /* CSS3 spec*/
}
// But don't let it screw up prepend/append inputs
.input-prepend input[class*="span"],
.input-append input[class*="span"] {
width: auto;
}
// Update checkboxes for iOS
input[type="checkbox"],
input[type="radio"] {
border: 1px solid #ccc;
}
// Remove the horizontal form styles
.form-horizontal .control-group > label {
float: none;
width: auto;
padding-top: 0;
text-align: left;
}
// Move over all input controls and content
.form-horizontal .controls {
margin-left: 0;
}
// Move the options list down to align with labels
.form-horizontal .control-list {
padding-top: 0; // has to be padding because margin collaspes
}
// Move over buttons in .form-actions to align with .controls
.form-horizontal .form-actions {
padding-left: 10px;
padding-right: 10px;
}
// Modals
.modal {
position: absolute;
top: 10px;
left: 10px;
right: 10px;
width: auto;
margin: 0;
&.fade.in { top: auto; }
}
.modal-header .close {
padding: 10px;
margin: -10px;
}
// Carousel
.carousel-caption {
position: static;
}
}
// LANDSCAPE PHONE TO SMALL DESKTOP & PORTRAIT TABLET
// --------------------------------------------------
@media (max-width: 767px) {
// GRID & CONTAINERS
// -----------------
// Remove width from containers
.container {
width: auto;
padding: 0 20px;
}
// Fluid rows
.row-fluid {
width: 100%;
}
// Undo negative margin on rows
.row {
margin-left: 0;
}
// Make all columns even
.row > [class*="span"],
.row-fluid > [class*="span"] {
float: none;
display: block;
width: auto;
margin: 0;
}
}
// PORTRAIT TABLET TO DEFAULT DESKTOP
// ----------------------------------
@media (min-width: 768px) and (max-width: 979px) {
// Fixed grid
#gridSystem > .generate(12, 42px, 20px);
// Fluid grid
#fluidGridSystem > .generate(12, 5.801104972%, 2.762430939%);
// Input grid
#inputGridSystem > .generate(12, 42px, 20px);
}
// TABLETS AND BELOW
// -----------------
@media (max-width: 979px) {
// UNFIX THE TOPBAR
// ----------------
// Remove any padding from the body
body {
padding-top: 0;
}
// Unfix the navbar
.navbar-fixed-top {
position: static;
margin-bottom: @baseLineHeight;
}
.navbar-fixed-top .navbar-inner {
padding: 5px;
}
.navbar .container {
width: auto;
padding: 0;
}
// Account for brand name
.navbar .brand {
padding-left: 10px;
padding-right: 10px;
margin: 0 0 0 -5px;
}
// Nav collapse clears brand
.navbar .nav-collapse {
clear: left;
}
// Block-level the nav
.navbar .nav {
float: none;
//margin: 0 0 (@baseLineHeight / 2);
}
.navbar .nav > li {
float: none;
}
.navbar .nav > li > a {
margin-bottom: 2px;
}
.navbar .nav > .divider-vertical {
display: none;
}
.navbar .nav .nav-header {
color: @navbarText;
text-shadow: none;
}
// Nav and dropdown links in navbar
.navbar .nav > li > a,
.navbar .dropdown-menu a {
padding: 6px 15px;
font-weight: bold;
color: @navbarLinkColor;
.border-radius(3px);
}
.navbar .dropdown-menu li + li a {
margin-bottom: 2px;
}
.navbar .nav > li > a:hover,
.navbar .dropdown-menu a:hover {
background-color: @navbarBackground;
}
// Dropdowns in the navbar
.navbar .dropdown-menu {
position: static;
top: auto;
left: auto;
float: none;
display: block;
max-width: none;
margin: 0 15px;
padding: 0;
background-color: transparent;
border: none;
.border-radius(0);
.box-shadow(none);
}
.navbar .dropdown-menu:before,
.navbar .dropdown-menu:after {
display: none;
}
.navbar .dropdown-menu .divider {
display: none;
}
// Forms in navbar
.navbar-form,
.navbar-search {
float: none;
//padding: (@baseLineHeight / 2) 15px;
//margin: (@baseLineHeight / 2) 0;
border-top: 1px solid @navbarBackground;
border-bottom: 1px solid @navbarBackground;
@shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);
.box-shadow(@shadow);
}
// Pull right (secondary) nav content
.navbar .nav.pull-right {
float: none;
margin-left: 0;
}
// Static navbar
.navbar-static .navbar-inner {
padding-left: 10px;
padding-right: 10px;
}
// Navbar button
.btn-navbar {
display: block;
}
// Hide everything in the navbar save .brand and toggle button */
.nav-collapse {
overflow: hidden;
height: 0;
}
}
// DEFAULT DESKTOP
// ---------------
@media (min-width: 980px) {
.nav-collapse.collapse {
height: auto !important;
}
}
// LARGE DESKTOP & UP
// ------------------
@media (min-width: 1200px) {
// Fixed grid
#gridSystem > .generate(12, 70px, 30px);
// Fluid grid
#fluidGridSystem > .generate(12, 5.982905983%, 2.564102564%);
// Input grid
#inputGridSystem > .generate(12, 70px, 30px);
// Thumbnails
.thumbnails {
margin-left: -30px;
}
.thumbnails > li {
margin-left: 30px;
}
}

View file

@ -0,0 +1,29 @@
// Scaffolding
// Basic and global styles for generating a grid system, structural layout, and page templates
// -------------------------------------------------------------------------------------------
// STRUCTURAL LAYOUT
// -----------------
body {
margin: 0;
font-family: @baseFontFamily;
font-size: @baseFontSize;
line-height: @baseLineHeight;
color: @textColor;
background-color: @white;
}
// LINKS
// -----
a {
color: @linkColor;
text-decoration: none;
}
a:hover {
color: @linkColorHover;
text-decoration: underline;
}

View file

@ -0,0 +1,460 @@
// SPRITES
// Glyphs and icons for buttons, nav, and more
// -------------------------------------------
// ICONS
// -----
// All icons receive the styles of the <i> tag with a base class
// of .i and are then given a unique class to add width, height,
// and background-position. Your resulting HTML will look like
// <i class="icon-inbox"></i>.
// For the white version of the icons, just add the .icon-white class:
// <i class="icon-inbox icon-white"></i>
[class^="icon-"],
[class*=" icon-"] {
display: inline-block;
width: 14px;
height: 14px;
line-height: 14px;
vertical-align: text-top;
background-image: url(@iconSpritePath);
background-position: 14px 14px;
background-repeat: no-repeat;
.ie7-restore-right-whitespace();
}
.icon-white {
background-image: url(@iconWhiteSpritePath);
}
.icon-grey {
background-image: url(@iconGreySpritePath);
}
.icon-glass {
background-position: 0 0;
}
.icon-music {
background-position: -24px 0;
}
.icon-search {
background-position: -48px 0;
}
.icon-envelope {
background-position: -72px 0;
}
.icon-heart {
background-position: -96px 0;
}
.icon-star {
background-position: -120px 0;
}
.icon-star-empty {
background-position: -144px 0;
}
.icon-user {
background-position: -168px 0;
}
.icon-film {
background-position: -192px 0;
}
.icon-th-large {
background-position: -216px 0;
}
.icon-th {
background-position: -240px 0;
}
.icon-th-list {
background-position: -264px 0;
}
.icon-ok {
background-position: -288px 0;
}
.icon-remove {
background-position: -312px 0;
}
.icon-zoom-in {
background-position: -336px 0;
}
.icon-zoom-out {
background-position: -360px 0;
}
.icon-off {
background-position: -384px 0;
}
.icon-signal {
background-position: -408px 0;
}
.icon-cog {
background-position: -432px 0;
}
.icon-trash {
background-position: -456px 0;
}
.icon-home {
background-position: 0 -24px;
}
.icon-file {
background-position: -24px -24px;
}
.icon-time {
background-position: -48px -24px;
}
.icon-road {
background-position: -72px -24px;
}
.icon-download-alt {
background-position: -96px -24px;
}
.icon-download {
background-position: -120px -24px;
}
.icon-upload {
background-position: -144px -24px;
}
.icon-inbox {
background-position: -168px -24px;
}
.icon-play-circle {
background-position: -192px -24px;
}
.icon-repeat {
background-position: -216px -24px;
}
.icon-refresh {
background-position: -240px -24px;
}
.icon-list-alt {
background-position: -264px -24px;
}
.icon-lock {
background-position: -287px -24px;
}
.icon-flag {
background-position: -312px -24px;
}
.icon-headphones {
background-position: -336px -24px;
}
.icon-volume-off {
background-position: -360px -24px;
}
.icon-volume-down {
background-position: -384px -24px;
}
.icon-volume-up {
background-position: -408px -24px;
}
.icon-qrcode {
background-position: -432px -24px;
}
.icon-barcode {
background-position: -456px -24px;
}
.icon-tag {
background-position: 0 -48px;
}
.icon-tags {
background-position: -25px -48px;
}
.icon-book {
background-position: -48px -48px;
}
.icon-bookmark {
background-position: -72px -48px;
}
.icon-print {
background-position: -96px -48px;
}
.icon-camera {
background-position: -120px -48px;
}
.icon-font {
background-position: -144px -48px;
}
.icon-bold {
background-position: -167px -48px;
}
.icon-italic {
background-position: -192px -48px;
}
.icon-text-height {
background-position: -216px -48px;
}
.icon-text-width {
background-position: -240px -48px;
}
.icon-align-left {
background-position: -264px -48px;
}
.icon-align-center {
background-position: -288px -48px;
}
.icon-align-right {
background-position: -312px -48px;
}
.icon-align-justify {
background-position: -336px -48px;
}
.icon-list {
background-position: -360px -48px;
}
.icon-indent-left {
background-position: -384px -48px;
}
.icon-indent-right {
background-position: -408px -48px;
}
.icon-facetime-video {
background-position: -432px -48px;
}
.icon-picture {
background-position: -456px -48px;
}
.icon-pencil {
background-position: 0 -72px;
}
.icon-map-marker {
background-position: -24px -72px;
}
.icon-adjust {
background-position: -48px -72px;
}
.icon-tint {
background-position: -72px -72px;
}
.icon-edit {
background-position: -96px -72px;
}
.icon-share {
background-position: -120px -72px;
}
.icon-check {
background-position: -144px -72px;
}
.icon-move {
background-position: -168px -72px;
}
.icon-step-backward {
background-position: -192px -72px;
}
.icon-fast-backward {
background-position: -216px -72px;
}
.icon-backward {
background-position: -240px -72px;
}
.icon-play {
background-position: -264px -72px;
}
.icon-pause {
background-position: -288px -72px;
}
.icon-stop {
background-position: -312px -72px;
}
.icon-forward {
background-position: -336px -72px;
}
.icon-fast-forward {
background-position: -360px -72px;
}
.icon-step-forward {
background-position: -384px -72px;
}
.icon-eject {
background-position: -408px -72px;
}
.icon-chevron-left {
background-position: -432px -72px;
}
.icon-chevron-right {
background-position: -456px -72px;
}
.icon-plus-sign {
background-position: 0 -96px;
}
.icon-minus-sign {
background-position: -24px -96px;
}
.icon-remove-sign {
background-position: -48px -96px;
}
.icon-ok-sign {
background-position: -72px -96px;
}
.icon-question-sign {
background-position: -96px -96px;
}
.icon-info-sign {
background-position: -120px -96px;
}
.icon-screenshot {
background-position: -144px -96px;
}
.icon-remove-circle {
background-position: -168px -96px;
}
.icon-ok-circle {
background-position: -192px -96px;
}
.icon-ban-circle {
background-position: -216px -96px;
}
.icon-arrow-left {
background-position: -240px -96px;
}
.icon-arrow-right {
background-position: -264px -96px;
}
.icon-arrow-up {
background-position: -289px -96px;
}
.icon-arrow-down {
background-position: -312px -96px;
}
.icon-share-alt {
background-position: -336px -96px;
}
.icon-resize-full {
background-position: -360px -96px;
}
.icon-resize-small {
background-position: -384px -96px;
}
.icon-plus {
background-position: -408px -96px;
}
.icon-minus {
background-position: -433px -96px;
}
.icon-asterisk {
background-position: -456px -96px;
}
.icon-exclamation-sign {
background-position: 0 -120px;
}
.icon-gift {
background-position: -24px -120px;
}
.icon-leaf {
background-position: -48px -120px;
}
.icon-fire {
background-position: -72px -120px;
}
.icon-eye-open {
background-position: -96px -120px;
}
.icon-eye-close {
background-position: -120px -120px;
}
.icon-warning-sign {
background-position: -144px -120px;
}
.icon-plane {
background-position: -168px -120px;
}
.icon-calendar {
background-position: -192px -120px;
}
.icon-random {
background-position: -216px -120px;
width: 16px;
}
.icon-comment {
background-position: -240px -120px;
}
.icon-magnet {
background-position: -264px -120px;
}
.icon-chevron-up {
background-position: -288px -120px;
}
.icon-chevron-down {
background-position: -313px -119px;
}
.icon-retweet {
background-position: -336px -120px;
}
.icon-shopping-cart {
background-position: -360px -120px;
}
.icon-folder-close {
background-position: -384px -120px;
width: 16px;
}
.icon-folder-open {
background-position: -408px -120px;
width: 16px;
}
.icon-resize-vertical {
background-position: -432px -119px;
}
.icon-resize-horizontal {
background-position: -456px -118px;
}
.icon-hdd {
background-position: 0 -144px;
}
.icon-bullhorn {
background-position: -24px -144px;
}
.icon-bell {
background-position: -48px -144px;
}
.icon-certificate {
background-position: -72px -144px;
}
.icon-thumbs-up {
background-position: -96px -144px;
}
.icon-thumbs-down {
background-position: -120px -144px;
}
.icon-hand-right {
background-position: -144px -144px;
}
.icon-hand-left {
background-position: -168px -144px;
}
.icon-hand-up {
background-position: -192px -144px;
}
.icon-hand-down {
background-position: -216px -144px;
}
.icon-circle-arrow-right {
background-position: -240px -144px;
}
.icon-circle-arrow-left {
background-position: -264px -144px;
}
.icon-circle-arrow-up {
background-position: -288px -144px;
}
.icon-circle-arrow-down {
background-position: -312px -144px;
}
.icon-globe {
background-position: -336px -144px;
}
.icon-wrench {
background-position: -360px -144px;
}
.icon-tasks {
background-position: -384px -144px;
}
.icon-filter {
background-position: -408px -144px;
}
.icon-briefcase {
background-position: -432px -144px;
}
.icon-fullscreen {
background-position: -456px -144px;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,150 @@
//
// Tables.less
// Tables for, you guessed it, tabular data
// ----------------------------------------
// BASE TABLES
// -----------------
table {
max-width: 100%;
border-collapse: collapse;
border-spacing: 0;
}
// BASELINE STYLES
// ---------------
.table {
width: 100%;
margin-bottom: @baseLineHeight;
// Cells
th,
td {
padding: 8px;
line-height: @baseLineHeight;
text-align: left;
vertical-align: top;
border-top: 1px solid #ddd;
}
th {
font-weight: bold;
}
// Bottom align for column headings
thead th {
vertical-align: bottom;
}
// Remove top border from thead by default
thead:first-child tr th,
thead:first-child tr td {
border-top: 0;
}
// Account for multiple tbody instances
tbody + tbody {
border-top: 2px solid #ddd;
}
}
// CONDENSED TABLE W/ HALF PADDING
// -------------------------------
.table-condensed {
th,
td {
padding: 4px 5px;
}
}
// BORDERED VERSION
// ----------------
.table-bordered {
border: 1px solid #ddd;
border-collapse: separate; // Done so we can round those corners!
*border-collapse: collapsed; // IE7 can't round corners anyway
.border-radius(4px);
th + th,
td + td,
th + td,
td + th {
border-left: 1px solid #ddd;
}
// Prevent a double border
thead:first-child tr:first-child th,
tbody:first-child tr:first-child th,
tbody:first-child tr:first-child td {
border-top: 0;
}
// For first th or td in the first row in the first thead or tbody
thead:first-child tr:first-child th:first-child,
tbody:first-child tr:first-child td:first-child {
.border-radius(4px 0 0 0);
}
thead:first-child tr:first-child th:last-child,
tbody:first-child tr:first-child td:last-child {
.border-radius(0 4px 0 0);
}
// For first th or td in the first row in the first thead or tbody
thead:last-child tr:last-child th:first-child,
tbody:last-child tr:last-child td:first-child {
.border-radius(0 0 0 4px);
}
thead:last-child tr:last-child th:last-child,
tbody:last-child tr:last-child td:last-child {
.border-radius(0 0 4px 0);
}
}
// ZEBRA-STRIPING
// --------------
// Default zebra-stripe styles (alternating gray and transparent backgrounds)
.table-striped {
tbody {
tr:nth-child(odd) td,
tr:nth-child(odd) th {
background-color: #f9f9f9;
}
}
}
// HOVER EFFECT
// ------------
// Placed here since it has to come after the potential zebra striping
.table {
tbody tr:hover td,
tbody tr:hover th {
background-color: #f5f5f5;
}
}
// TABLE CELL SIZING
// -----------------
// Change the columns
.tableColumns(@columnSpan: 1) {
float: none;
//width: ((@gridColumnWidth) * @columnSpan) + (@gridGutterWidth * (@columnSpan - 1)) - 16;
margin-left: 0;
}
table {
.span1 { .tableColumns(1); }
.span2 { .tableColumns(2); }
.span3 { .tableColumns(3); }
.span4 { .tableColumns(4); }
.span5 { .tableColumns(5); }
.span6 { .tableColumns(6); }
.span7 { .tableColumns(7); }
.span8 { .tableColumns(8); }
.span9 { .tableColumns(9); }
.span10 { .tableColumns(10); }
.span11 { .tableColumns(11); }
.span12 { .tableColumns(12); }
}

View file

@ -0,0 +1,35 @@
// THUMBNAILS
// ----------
.thumbnails {
margin-left: -@gridGutterWidth;
list-style: none;
.clearfix();
}
.thumbnails > li {
float: left;
margin: 0 0 @baseLineHeight @gridGutterWidth;
}
.thumbnail {
display: block;
padding: 4px;
line-height: 1;
border: 1px solid #ddd;
.border-radius(4px);
.box-shadow(0 1px 1px rgba(0,0,0,.075));
}
// Add a hover state for linked versions only
a.thumbnail:hover {
border-color: @linkColor;
.box-shadow(0 1px 4px rgba(0,105,214,.25));
}
// Images and captions
.thumbnail > img {
display: block;
max-width: 100%;
margin-left: auto;
margin-right: auto;
}
.thumbnail .caption {
padding: 9px;
}

View file

@ -0,0 +1,10 @@
body {
background-color: #ececec;
font-family: Arial, Verdana, sans-serif;
font-size: 12px;
color: #000;
text-align: justify;
line-height: 16px;
margin: 10px;
}

View file

@ -0,0 +1,35 @@
// TOOLTIP
// ------=
.tooltip {
position: absolute;
z-index: @zindexTooltip;
display: block;
visibility: visible;
padding: 5px;
font-size: 11px;
.opacity(0);
&.in { .opacity(80); }
&.top { margin-top: -2px; }
&.right { margin-left: 2px; }
&.bottom { margin-top: 2px; }
&.left { margin-left: -2px; }
&.top .tooltip-arrow { #popoverArrow > .top(); }
&.left .tooltip-arrow { #popoverArrow > .left(); }
&.bottom .tooltip-arrow { #popoverArrow > .bottom(); }
&.right .tooltip-arrow { #popoverArrow > .right(); }
}
.tooltip-inner {
max-width: 200px;
padding: 3px 8px;
color: @white;
text-align: center;
text-decoration: none;
background-color: @black;
.border-radius(4px);
}
.tooltip-arrow {
position: absolute;
width: 0;
height: 0;
}

View file

@ -0,0 +1,220 @@
// Typography.less
// Headings, body text, lists, code, and more for a versatile and durable typography system
// ----------------------------------------------------------------------------------------
// BODY TEXT
// ---------
p {
//margin: 0 0 @baseLineHeight / 2;
font-family: @baseFontFamily;
font-size: @baseFontSize;
line-height: @baseLineHeight;
small {
//font-size: @baseFontSize - 2;
color: @grayLight;
}
}
.lead {
margin-bottom: @baseLineHeight;
font-size: 20px;
font-weight: 200;
//line-height: @baseLineHeight * 1.5;
}
// HEADINGS
// --------
h1, h2, h3, h4, h5, h6 {
margin:10px 0;
font-weight: bold;
color: @grayDark;
text-rendering: optimizelegibility; // Fix the character spacing for headings
small {
font-weight: normal;
color: @grayLight;
}
}
h1 {
font-size: 30px;
//line-height: @baseLineHeight * 2;
margin:15px 0;
small {
font-size: 18px;
}
}
h2 {
font-size: 24px;
//line-height: @baseLineHeight * 2;
small {
font-size: 18px;
}
}
h3 {
//line-height: @baseLineHeight * 1.5;
font-size: 18px;
small {
font-size: 14px;
}
}
h4, h5, h6 {
line-height: @baseLineHeight;
}
h4 {
font-size: 14px;
small {
font-size: 12px;
}
}
h5 {
font-size: 12px;
}
h6 {
font-size: 11px;
color: @grayLight;
text-transform: uppercase;
}
// Page header
.page-header {
//padding-bottom: @baseLineHeight - 1;
margin: @baseLineHeight 0;
border-bottom: 1px solid @grayLighter;
}
.page-header h1 {
line-height: 1;
}
// LISTS
// -----
// Unordered and Ordered lists
ul, ol {
padding: 0;
//margin: 0 0 @baseLineHeight / 2 25px;
}
ul ul,
ul ol,
ol ol,
ol ul {
margin-bottom: 0;
}
ul {
list-style: disc;
}
ol {
list-style: decimal;
}
li {
line-height: @baseLineHeight;
list-style:none;
}
ul.unstyled,
ol.unstyled {
margin-left: 0;
list-style: none;
}
// Description Lists
dl {
margin-bottom: @baseLineHeight;
}
dt,
dd {
line-height: @baseLineHeight;
}
dt {
font-weight: bold;
}
dd {
//margin-left: @baseLineHeight / 2;
}
// MISC
// ----
// Horizontal rules
hr {
margin: @baseLineHeight 0;
border: 0;
border-top: 1px solid @hrBorder;
border-bottom: 1px solid @white;
}
// Emphasis
strong {
font-weight: bold;
}
em {
font-style: italic;
}
.muted {
color: @grayLight;
}
// Abbreviations and acronyms
abbr {
font-size: 90%;
text-transform: uppercase;
border-bottom: 1px dotted #ddd;
cursor: help;
}
// Blockquotes
blockquote {
padding: 0 0 0 15px;
margin: 0 0 @baseLineHeight;
border-left: 5px solid @grayLighter;
p {
margin-bottom: 0;
#font > .shorthand(16px,300,@baseLineHeight * 1.25);
}
small {
display: block;
line-height: @baseLineHeight;
color: @grayLight;
&:before {
content: '\2014 \00A0';
}
}
// Float right with text-align: right
&.pull-right {
float: right;
padding-left: 0;
padding-right: 15px;
border-left: 0;
border-right: 5px solid @grayLighter;
p,
small {
text-align: right;
}
}
}
// Quotes
q:before,
q:after,
blockquote:before,
blockquote:after {
content: "";
}
// Addresses
address {
display: block;
margin-bottom: @baseLineHeight;
line-height: @baseLineHeight;
font-style: normal;
}
// Misc
small {
font-size: 100%;
}
cite {
font-style: normal;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Some files were not shown because too many files have changed in this diff Show more