-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathlistener.php
124 lines (108 loc) · 3.25 KB
/
listener.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
<?php
/**
* @package s9e\highlighter
* @copyright Copyright (c) 2015-2021 The s9e authors
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
namespace s9e\highlighter;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use phpbb\cache\service as cache;
use phpbb\template\twig\twig;
use s9e\TextFormatter\Bundles\Forum;
class listener implements EventSubscriberInterface
{
protected $cache;
protected $hasCode = false;
protected $template;
public function __construct(cache $cache, twig $template)
{
$this->cache = $cache;
$this->template = $template;
}
public static function getSubscribedEvents()
{
return [
'core.text_formatter_s9e_configure_after' => 'onConfigure',
'core.text_formatter_s9e_render_before' => 'onRender'
];
}
public function onConfigure($event)
{
$configurator = $event['configurator'];
if (!isset($configurator->tags['CODE'], $configurator->BBCodes['CODE']))
{
return;
}
$configurator->BBCodes['CODE']->defaultAttribute = 'lang';
if (!isset($configurator->tags['CODE']->attributes['lang']))
{
$attribute = $configurator->tags['CODE']->attributes->add('lang');
$attribute->required = false;
$attribute->filterChain->append('#identifier');
}
$attribute = $configurator->tags['CODE']->attributes['lang'];
$attribute->filterChain->prepend('#map')->setMap(
[
'c#' => 'csharp',
'c++' => 'cpp',
'f#' => 'fsharp'
],
false
);
$attribute->filterChain->prepend('strtolower');
$dom = $configurator->tags['CODE']->template->asDOM();
foreach ($dom->getElementsByTagName('code') as $code)
{
$code->setAttribute('class', trim($code->getAttribute('class') . ' language-{@lang}'));
}
foreach ($dom->getElementsByTagName('pre') as $pre)
{
$pre->setAttribute('data-s9e-livepreview-hash', '');
$pre->setAttribute('data-s9e-livepreview-onupdate', "if(typeof hljsLoader!=='undefined')hljsLoader.highlightBlocks(this)");
}
$dom->saveChanges();
}
public function onRender($event)
{
if ($this->hasCode || strpos($event['xml'], '<CODE') === false)
{
return;
}
$this->hasCode = true;
$parameters = $this->cache->get('s9e_highlighter_parameters');
if (!$parameters)
{
$parameters = $this->getTemplateParameters();
$this->cache->put('s9e_highlighter_parameters', $parameters);
}
foreach ($parameters as $k => $v)
{
$this->template->assign_var('s9e_highlighter_' . $k, $v);
}
}
protected function getTemplateParameters(): array
{
$parameters = [
'hljs_options' => '',
'hljs_style' => 'github',
'hljs_url' => '',
'needs_loader' => 1,
'script_integrity' => 'sha384-0R2eSjxhS3nwxyF5hfN2eeJ2m+X1s6yA8sb5pK7+/haZVPDRqEZIAQvSK4isiB5K',
'script_src' => 'https://cdn.jsdelivr.net/gh/s9e/hljs-loader@1.0.19/loader.min.js'
];
$html = Forum::render('<r><CODE></CODE></r>');
preg_match_all('((\\w++)="([^"]++))', $html, $m);
$values = array_map('htmlspecialchars_decode', array_combine($m[1], $m[2]));
$map = [
'integrity' => 'script_integrity',
'options' => 'hljs_options',
'src' => 'script_src',
'url' => 'hljs_url'
];
foreach (array_intersect_key($values, $map) as $k => $v)
{
$parameters[$map[$k]] = $v;
}
return $parameters;
}
}