mirror of
https://github.com/flarum/core.git
synced 2025-10-11 23:14:29 +02:00
Falls back to a less effective minification library if ClosureCompilerService errors or is unavailable. Minification takes a while (20 seconds or so), but it only happens when assets are modified. Still, this means enabling/disabling extensions is taking far too long. Possible solutions: - Don't minify initially; set a process running in the background to do minification, and server unminified assets in the meantime. - Refactor compiler to send each JS file to CCS individually, only if that particular file has been modified. flarum/gulp has also been updated to no longer support uglification. closes #582
207 lines
4.7 KiB
PHP
207 lines
4.7 KiB
PHP
<?php
|
|
/*
|
|
* This file is part of Flarum.
|
|
*
|
|
* (c) Toby Zerner <toby.zerner@gmail.com>
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace Flarum\Formatter;
|
|
|
|
use Illuminate\Contracts\Cache\Repository;
|
|
use Illuminate\Contracts\Events\Dispatcher;
|
|
use s9e\TextFormatter\Configurator;
|
|
use s9e\TextFormatter\Unparser;
|
|
use Flarum\Event\ConfigureFormatter;
|
|
use Flarum\Event\ConfigureFormatterParser;
|
|
use Flarum\Event\ConfigureFormatterRenderer;
|
|
|
|
class Formatter
|
|
{
|
|
/**
|
|
* @var Repository
|
|
*/
|
|
protected $cache;
|
|
|
|
/**
|
|
* @var Dispatcher
|
|
*/
|
|
protected $events;
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
protected $cacheDir;
|
|
|
|
/**
|
|
* @param Repository $cache
|
|
* @param Dispatcher $events
|
|
* @param string $cacheDir
|
|
*/
|
|
public function __construct(Repository $cache, Dispatcher $events, $cacheDir)
|
|
{
|
|
$this->cache = $cache;
|
|
$this->events = $events;
|
|
$this->cacheDir = $cacheDir;
|
|
}
|
|
|
|
/**
|
|
* Parse text.
|
|
*
|
|
* @param string $text
|
|
* @param mixed $context
|
|
* @return string
|
|
*/
|
|
public function parse($text, $context = null)
|
|
{
|
|
$parser = $this->getParser($context);
|
|
|
|
return $parser->parse($text);
|
|
}
|
|
|
|
/**
|
|
* Render parsed XML.
|
|
*
|
|
* @param string $xml
|
|
* @param mixed $context
|
|
* @return string
|
|
*/
|
|
public function render($xml, $context = null)
|
|
{
|
|
$renderer = $this->getRenderer($context);
|
|
|
|
return $renderer->render($xml);
|
|
}
|
|
|
|
/**
|
|
* Unparse XML.
|
|
*
|
|
* @param string $xml
|
|
* @return string
|
|
*/
|
|
public function unparse($xml)
|
|
{
|
|
return Unparser::unparse($xml);
|
|
}
|
|
|
|
/**
|
|
* Flush the cache so that the formatter components are regenerated.
|
|
*/
|
|
public function flush()
|
|
{
|
|
$this->cache->forget('flarum.formatter.parser');
|
|
$this->cache->forget('flarum.formatter.renderer');
|
|
}
|
|
|
|
/**
|
|
* @return Configurator
|
|
*/
|
|
protected function getConfigurator()
|
|
{
|
|
$configurator = new Configurator;
|
|
|
|
$configurator->rootRules->enableAutoLineBreaks();
|
|
|
|
$configurator->rendering->engine = 'PHP';
|
|
$configurator->rendering->engine->cacheDir = $this->cacheDir;
|
|
|
|
$configurator->Escaper;
|
|
$configurator->Autoemail;
|
|
$configurator->Autolink;
|
|
$configurator->tags->onDuplicate('replace');
|
|
|
|
$this->events->fire(new ConfigureFormatter($configurator));
|
|
|
|
$this->configureExternalLinks($configurator);
|
|
|
|
return $configurator;
|
|
}
|
|
|
|
/**
|
|
* @param Configurator $configurator
|
|
*/
|
|
protected function configureExternalLinks(Configurator $configurator)
|
|
{
|
|
$dom = $configurator->tags['URL']->template->asDOM();
|
|
|
|
foreach ($dom->getElementsByTagName('a') as $a) {
|
|
$a->setAttribute('target', '_blank');
|
|
$a->setAttribute('rel', 'nofollow');
|
|
}
|
|
|
|
$dom->saveChanges();
|
|
}
|
|
|
|
/**
|
|
* Get a TextFormatter component.
|
|
*
|
|
* @param string $name "renderer" or "parser"
|
|
* @return mixed
|
|
*/
|
|
protected function getComponent($name)
|
|
{
|
|
$cacheKey = 'flarum.formatter.' . $name;
|
|
|
|
return $this->cache->rememberForever($cacheKey, function () use ($name) {
|
|
return $this->getConfigurator()->finalize()[$name];
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Get the parser.
|
|
*
|
|
* @param mixed $context
|
|
* @return \s9e\TextFormatter\Parser
|
|
*/
|
|
protected function getParser($context = null)
|
|
{
|
|
$parser = $this->getComponent('parser');
|
|
|
|
$parser->registeredVars['context'] = $context;
|
|
|
|
$this->events->fire(new ConfigureFormatterParser($parser, $context));
|
|
|
|
return $parser;
|
|
}
|
|
|
|
/**
|
|
* Get the renderer.
|
|
*
|
|
* @param mixed $context
|
|
* @return \s9e\TextFormatter\Renderer
|
|
*/
|
|
protected function getRenderer($context = null)
|
|
{
|
|
spl_autoload_register(function ($class) {
|
|
if (file_exists($file = $this->cacheDir.'/'.$class.'.php')) {
|
|
include $file;
|
|
}
|
|
});
|
|
|
|
$renderer = $this->getComponent('renderer');
|
|
|
|
$this->events->fire(new ConfigureFormatterRenderer($renderer, $context));
|
|
|
|
return $renderer;
|
|
}
|
|
|
|
/**
|
|
* Get the formatter JavaScript.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getJs()
|
|
{
|
|
$configurator = $this->getConfigurator();
|
|
$configurator->enableJavaScript();
|
|
$configurator->javascript->exportMethods = ['preview'];
|
|
|
|
return $configurator->finalize([
|
|
'returnParser' => false,
|
|
'returnRenderer' => false
|
|
])['js'];
|
|
}
|
|
}
|