--- /dev/null
+<div class="codeBox collapsibleBbcode jsCollapsibleBbcode {$highlighter|get_class|substr:30|lcfirst}{if $lines > 10} collapsed{/if}">
+ <div>
+ <div class="codeBoxHeader">
+ <div class="codeBoxHeadline">{@$highlighter->getTitle()}{if $filename}: {$filename}{/if}</div>
+ </div>
+
+ <ol start="{$startLineNumber}">
+ {assign var='lineNumber' value=$startLineNumber}
+ {foreach from=$content item=line}
+ {if $lineNumbers[$lineNumber]|isset}
+ <li id="{@$lineNumbers[$lineNumber]}"><a href="{@$__wcf->getAnchor($lineNumbers[$lineNumber])}" class="lineAnchor"></a>{@$line}</li>
+ {else}
+ <li>{@$line}</li>
+ {/if}
+
+ {assign var='lineNumber' value=$lineNumber+1}
+ {/foreach}
+ </ol>
+ </div>
+
+ {if $lines > 10}
+ <span class="toggleButton" data-title-collapse="{lang}wcf.bbcode.button.collapse{/lang}" data-title-expand="{lang}wcf.bbcode.button.showAll{/lang}">{lang}wcf.bbcode.button.showAll{/lang}</span>
+
+ {if !$__overlongCodeBoxSeen|isset}
+ {assign var='__overlongCodeBoxSeen' value=true}
+ <script data-relocate="true">
+ require(['WoltLab/WCF/Bbcode/Collapsible'], function(BbcodeCollapsible) {
+ BbcodeCollapsible.observe();
+ });
+ </script>
+ {/if}
+ {/if}
+</div>
--- /dev/null
+<!-- begin:parser_nonessential -->
+<div class="spoilerBox jsSpoilerBox">
+ <header class="jsOnly">
+ <a class="button small jsSpoilerToggle"{if $buttonLabel} data-has-custom-label="true"{/if}>{if $buttonLabel}{$buttonLabel}{else}{lang}wcf.bbcode.spoiler.show{/lang}{/if}</a>
+ </header>
+
+ <div style="display: none">
+ <!-- META_CODE_INNER_CONTENT -->
+ </div>
+</div>
+
+{if !$__wcfSpoilerBBCodeJavaScript|isset}
+ {assign var='__wcfSpoilerBBCodeJavaScript' value=true}
+ <script data-relocate="true">
+ elBySelAll('.jsSpoilerBox', null, function(spoilerBox) {
+ spoilerBox.classList.remove('jsSpoilerBox');
+
+ var toggleButton = elBySel('.jsSpoilerToggle', spoilerBox);
+ var container = toggleButton.parentNode.nextElementSibling;
+
+ toggleButton.addEventListener(WCF_CLICK_EVENT, function(event) {
+ event.preventDefault();
+
+ toggleButton.classList.toggle('active');
+ window[(toggleButton.classList.contains('active') ? 'elShow' : 'elHide')](container);
+
+ if (!elDataBool(toggleButton, 'has-custom-label')) {
+ toggleButton.textContent = (toggleButton.classList.contains('active')) ? '{lang}wcf.bbcode.spoiler.hide{/lang}' : '{lang}wcf.bbcode.spoiler.show{/lang}';
+ }
+ });
+ });
+ </script>
+{/if}
+<!-- end:parser_nonessential -->
* @protected
*/
_observeLoad: function() {
- this._editor.events.stopDetectChanges();
-
elBySelAll('pre', this._editor.$editor[0], (function(pre) {
pre.addEventListener(WCF_CLICK_EVENT, this._callbackEdit);
this._setTitle(pre);
}).bind(this));
-
- this._editor.events.startDetectChanges();
},
/**
_save: function(event) {
event.preventDefault();
- this._editor.events.stopDetectChanges();
-
var id = 'redactor-code-' + this._elementId;
['file', 'highlighter', 'line'].forEach((function (attr) {
this._setTitle(this._pre);
this._editor.caret.after(this._pre);
- this._editor.events.startDetectChanges();
-
UiDialog.close(this);
},
* @protected
*/
_observeLoad: function() {
- this._editor.events.stopDetectChanges();
-
elBySelAll('blockquote', this._editor.$editor[0], (function(blockquote) {
blockquote.addEventListener(WCF_CLICK_EVENT, this._callbackEdit);
this._setTitle(blockquote);
}).bind(this));
-
- this._editor.events.startDetectChanges();
},
/**
_save: function(event) {
event.preventDefault();
- this._editor.events.stopDetectChanges();
-
var id = 'redactor-quote-' + this._elementId;
['author', 'url'].forEach((function (attr) {
this._setTitle(this._blockquote);
this._editor.caret.after(this._blockquote);
- this._editor.events.startDetectChanges();
-
UiDialog.close(this);
},
* @protected
*/
_observeLoad: function() {
- this._editor.events.stopDetectChanges();
-
elBySelAll('woltlab-spoiler', this._editor.$editor[0], (function(spoiler) {
spoiler.addEventListener(WCF_CLICK_EVENT, this._callbackEdit);
this._setTitle(spoiler);
}).bind(this));
-
- this._editor.events.startDetectChanges();
},
/**
_save: function(event) {
event.preventDefault();
- this._editor.events.stopDetectChanges();
-
elData(this._spoiler, 'label', elById('redactor-spoiler-' + this._elementId + '-label').value);
this._setTitle(this._spoiler);
this._editor.caret.after(this._spoiler);
- this._editor.events.startDetectChanges();
-
UiDialog.close(this);
},
+++ /dev/null
-<?php
-namespace wcf\system\bbcode\highlighter;
-
-/**
- * Highlights syntax of brainfuck.
- *
- * @author Tim Duesterhus
- * @copyright 2001-2016 WoltLab GmbH
- * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\Bbcode\Highlighter
- */
-class BrainfuckHighlighter extends Highlighter {
- /**
- * @inheritDoc
- */
- public function highlight($string) {
- $string = preg_replace('/[^-\\+\\.,\\[\\]\\>\\<]+/', '||span class="hlComments"||\\0||/span||', $string);
- $string = preg_replace('/[\\<\\>]+/', '<span class="hlKeywords4">\\0</span>', $string);
- $string = preg_replace('/[-\\+]+/', '<span class="hlKeywords1">\\0</span>', $string);
- $string = preg_replace('/[\\.,]+/', '<span class="hlKeywords2">\\0</span>', $string);
- $string = preg_replace('/[\\[\\]]+/', '<span class="hlKeywords3">\\0</span>', $string);
-
- $string = str_replace(['||span class="hlComments"||', '||/span||'], ['<span class="hlComments">', '</span>'], $string);
- return $string;
- }
-}
protected function setAttributeDefinitions(\HTMLPurifier_Config $config) {
// TODO: move this into own PHP classes
$definition = $config->getHTMLDefinition(true);
- $definition->addAttribute('blockquote', 'data-quote-title', 'Text');
- $definition->addAttribute('blockquote', 'data-quote-url', 'URI');
+ // quotes
+ $definition->addAttribute('blockquote', 'data-author', 'Text');
+ $definition->addAttribute('blockquote', 'data-url', 'URI');
+
+ // code
+ $definition->addAttribute('pre', 'data-file', 'Text');
+ $definition->addAttribute('pre', 'data-line', 'Number');
+ $definition->addAttribute('pre', 'data-highlighter', 'Text');
+
+ // color
$definition->addElement('woltlab-color', 'Inline', 'Inline', '', ['class' => 'Text']);
+
+ // size
$definition->addElement('woltlab-size', 'Inline', 'Inline', '', ['class' => 'Text']);
+ // mention
$definition->addElement('woltlab-mention', 'Inline', 'Inline', '', [
'data-user-id' => 'Number',
'data-username' => 'Text'
]);
+ // spoiler
+ $definition->addElement('woltlab-spoiler', 'Block', 'Flow', '', [
+ 'data-label' => 'Text'
+ ]);
+
+ // generic metacode
$definition->addElement('woltlab-metacode', 'Inline', 'Inline', '', [
'data-attributes' => 'Text',
'data-name' => 'Text'
]);
+ // metacode markers
$definition->addElement('woltlab-metacode-marker', 'Inline', 'Empty', '', [
'data-attributes' => 'Text',
'data-name' => 'Text',
--- /dev/null
+<?php
+namespace wcf\system\html\metacode\converter;
+
+/**
+ * TOOD documentation
+ * @since 3.0
+ */
+class CodeMetacodeConverter extends AbstractMetacodeConverter {
+ /**
+ * @inheritDoc
+ */
+ public function convert(\DOMDocumentFragment $fragment, array $attributes) {
+ $element = $fragment->ownerDocument->createElement('pre');
+
+ $line = 1;
+ $highlighter = $file = '';
+
+ switch (count($attributes)) {
+ case 1:
+ if (is_numeric($attributes[0])) {
+ $line = intval($attributes[0]);
+ }
+ else if (mb_strpos($attributes[0], '.') === false) {
+ $highlighter = $attributes[0];
+ }
+ else {
+ $file = $attributes[0];
+ }
+ break;
+
+ case 2:
+ if (is_numeric($attributes[0])) {
+ $line = intval($attributes[0]);
+ if (mb_strpos($attributes[1], '.') === false) {
+ $highlighter = $attributes[1];
+ }
+ else {
+ $file = $attributes[1];
+ }
+ }
+ else {
+ $highlighter = $attributes[0];
+ $file = $attributes[1];
+ }
+ break;
+
+ default:
+ $highlighter = $attributes[0];
+ $line = intval($attributes[1]);
+ $file = $attributes[2];
+ break;
+ }
+
+ $element->setAttribute('data-file', $file);
+ $element->setAttribute('data-highlighter', $highlighter);
+ $element->setAttribute('data-line', $line);
+
+ $element->appendChild($fragment);
+
+ return $element;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function validateAttributes(array $attributes) {
+ // 0-3 attributes
+ return (count($attributes) <= 3);
+ }
+}
--- /dev/null
+<?php
+namespace wcf\system\html\metacode\converter;
+use wcf\util\StringUtil;
+
+/**
+ * TOOD documentation
+ * @since 3.0
+ */
+class SpoilerMetacodeConverter extends AbstractMetacodeConverter {
+ /**
+ * @inheritDoc
+ */
+ public function convert(\DOMDocumentFragment $fragment, array $attributes) {
+ $element = $fragment->ownerDocument->createElement('woltlab-spoiler');
+ $element->setAttribute('data-label', (!empty($attributes[0])) ? StringUtil::trim($attributes[0]) : '');
+ $element->appendChild($fragment);
+
+ return $element;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function validateAttributes(array $attributes) {
+ // 0 or 1 attribute
+ return (count($attributes) <= 1);
+ }
+}
protected $xpath;
public function load($html) {
- $this->document = new \DOMDocument();
+ $this->document = new \DOMDocument('1.0', 'UTF-8');
$this->xpath = null;
- // convert entities as DOMDocument screws them up
- $html = mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8');
-
// ignore all errors when loading the HTML string, because DOMDocument does not
// provide a proper way to add custom HTML elements (even though explicitly allowed
// in HTML5) and the input HTML has already been sanitized by HTMLPurifier
- @$this->document->loadHTML($html);
+ //
+ // we're also injecting a bogus meta tag that magically enables DOMDocument
+ // to handle UTF-8 properly, this avoids encoding non-ASCII characters as it
+ // would conflict with already existing entities when reverting them
+ @$this->document->loadHTML('<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />' . $html);
$this->nodeData = [];
}
public function getHtml() {
- $html = $this->document->saveHTML();
+ $html = $this->document->saveHTML($this->document->getElementsByTagName('body')->item(0));
// remove nuisance added by PHP
- $html = preg_replace('~^<!DOCTYPE[^>]+>\s<html><body>~', '', $html);
- $html = preg_replace('~</body></html>$~', '', $html);
-
- $html = mb_convert_encoding($html, 'UTF-8', 'HTML-ENTITIES');
+ $html = preg_replace('~^<body>~', '', $html);
+ $html = preg_replace('~</body>$~', '', $html);
/** @var IHtmlNode $obj */
foreach ($this->nodeData as $data) {
$obj = $data['object'];
$string = $obj->replaceTag($data['data']);
- $html = preg_replace_callback('~<wcfNode-' . $data['identifier'] . '>(?P<content>.*)</wcfNode-' . $data['identifier'] . '>~', function($matches) use ($string) {
+ $html = preg_replace_callback('~<wcfNode-' . $data['identifier'] . '>(?P<content>[\s\S]*)</wcfNode-' . $data['identifier'] . '>~', function($matches) use ($string) {
$string = str_replace('<!-- META_CODE_INNER_CONTENT -->', $matches['content'], $string);
return $string;
* @inheritDoc
*/
public function process(array $elements, HtmlNodeProcessor $htmlNodeProcessor) {
+ /** @var \DOMElement $element */
foreach ($elements as $element) {
- if ($element->getAttribute('class') === 'quoteBox') {
- $nodeIdentifier = StringUtil::getRandomID();
- $htmlNodeProcessor->addNodeData($this, $nodeIdentifier, [
- 'title' => ($element->hasAttribute('data-quote-title')) ? $element->getAttribute('data-quote-title') : '',
- 'url' => ($element->hasAttribute('data-quote-url')) ? $element->getAttribute('data-quote-url') : ''
- ]);
-
- $htmlNodeProcessor->renameTag($element, 'wcfNode-' . $nodeIdentifier);
- }
- else {
- $htmlNodeProcessor->unwrapContent($element);
- }
+ $nodeIdentifier = StringUtil::getRandomID();
+ $htmlNodeProcessor->addNodeData($this, $nodeIdentifier, [
+ 'title' => ($element->hasAttribute('data-quote-title')) ? $element->getAttribute('data-quote-title') : '',
+ 'url' => ($element->hasAttribute('data-quote-url')) ? $element->getAttribute('data-quote-url') : ''
+ ]);
+
+ $htmlNodeProcessor->renameTag($element, 'wcfNode-' . $nodeIdentifier);
}
}
--- /dev/null
+<?php
+namespace wcf\system\html\output\node;
+use wcf\system\bbcode\highlighter\BashHighlighter;
+use wcf\system\bbcode\highlighter\CHighlighter;
+use wcf\system\bbcode\highlighter\DiffHighlighter;
+use wcf\system\bbcode\highlighter\HtmlHighlighter;
+use wcf\system\bbcode\highlighter\JavaHighlighter;
+use wcf\system\bbcode\highlighter\JsHighlighter;
+use wcf\system\bbcode\highlighter\PerlHighlighter;
+use wcf\system\bbcode\highlighter\PhpHighlighter;
+use wcf\system\bbcode\highlighter\PlainHighlighter;
+use wcf\system\bbcode\highlighter\PythonHighlighter;
+use wcf\system\bbcode\highlighter\SqlHighlighter;
+use wcf\system\bbcode\highlighter\TexHighlighter;
+use wcf\system\bbcode\highlighter\XmlHighlighter;
+use wcf\system\html\node\AbstractHtmlNode;
+use wcf\system\html\node\HtmlNodeProcessor;
+use wcf\system\Regex;
+use wcf\system\WCF;
+use wcf\util\StringUtil;
+
+/**
+ * TOOD documentation
+ * @since 3.0
+ */
+class HtmlOutputNodePre extends AbstractHtmlNode {
+ protected $tagName = 'pre';
+
+ /**
+ * already used ids for line numbers to prevent duplicate ids in the output
+ * @var string[]
+ */
+ private static $codeIDs = [];
+
+ /**
+ * @inheritDoc
+ */
+ public function process(array $elements, HtmlNodeProcessor $htmlNodeProcessor) {
+ /** @var \DOMElement $element */
+ foreach ($elements as $element) {
+ $nodeIdentifier = StringUtil::getRandomID();
+ $htmlNodeProcessor->addNodeData($this, $nodeIdentifier, [
+ 'content' => $element->textContent,
+ 'file' => ($element->hasAttribute('data-file')) ? $element->getAttribute('data-file') : '',
+ 'highlighter' => ($element->hasAttribute('data-highlighter')) ? $element->getAttribute('data-highlighter') : '',
+ 'line' => ($element->hasAttribute('data-line')) ? $element->getAttribute('data-line') : 1
+ ]);
+
+ $htmlNodeProcessor->renameTag($element, 'wcfNode-' . $nodeIdentifier);
+ }
+ }
+
+ public function replaceTag(array $data) {
+ $content = preg_replace('/^\s*\n/', '', $data['content']);
+ $content = preg_replace('/\n\s*$/', '', $content);
+
+ $file = $data['file'];
+ $highlighter = $data['highlighter'];
+ $line = ($data['line'] < 1) ? 1 : $data['line'];
+
+ // fetch highlighter-classname
+ $className = PlainHighlighter::class;
+
+ // no highlighting for strings over a certain size, to prevent DoS
+ // this serves as a safety net in case one of the regular expressions
+ // in a highlighter causes PCRE to exhaust resources, such as the stack
+ if (strlen($content) < 16384) {
+ if ($highlighter) {
+ $className = '\wcf\system\bbcode\highlighter\\'.StringUtil::firstCharToUpperCase(mb_strtolower($highlighter)).'Highlighter';
+
+ switch (mb_substr($className, strlen('\wcf\system\bbcode\highlighter\\'))) {
+ case 'ShellHighlighter':
+ $className = BashHighlighter::class;
+ break;
+
+ case 'C++Highlighter':
+ $className = CHighlighter::class;
+ break;
+
+ case 'JavascriptHighlighter':
+ $className = JsHighlighter::class;
+ break;
+
+ case 'LatexHighlighter':
+ $className = TexHighlighter::class;
+ break;
+ }
+ }
+ else {
+ // try to guess highlighter
+ if (mb_strpos($content, '<?php') !== false) {
+ $className = PhpHighlighter::class;
+ }
+ else if (mb_strpos($content, '<html') !== false) {
+ $className = HtmlHighlighter::class;
+ }
+ else if (mb_strpos($content, '<?xml') === 0) {
+ $className = XmlHighlighter::class;
+ }
+ else if ( mb_strpos($content, 'SELECT') === 0
+ || mb_strpos($content, 'UPDATE') === 0
+ || mb_strpos($content, 'INSERT') === 0
+ || mb_strpos($content, 'DELETE') === 0) {
+ $className = SqlHighlighter::class;
+ }
+ else if (mb_strpos($content, 'import java.') !== false) {
+ $className = JavaHighlighter::class;
+ }
+ else if ( mb_strpos($content, "---") !== false
+ && mb_strpos($content, "\n+++") !== false) {
+ $className = DiffHighlighter::class;
+ }
+ else if (mb_strpos($content, "\n#include ") !== false) {
+ $className = CHighlighter::class;
+ }
+ else if (mb_strpos($content, '#!/usr/bin/perl') === 0) {
+ $className = PerlHighlighter::class;
+ }
+ else if (mb_strpos($content, 'def __init__(self') !== false) {
+ $className = PythonHighlighter::class;
+ }
+ else if (Regex::compile('^#!/bin/(ba|z)?sh')->match($content)) {
+ $className = BashHighlighter::class;
+ }
+ else if (mb_strpos($content, '\\documentclass') !== false) {
+ $className = TexHighlighter::class;
+ }
+ }
+ }
+
+ if (!class_exists($className)) {
+ $className = PlainHighlighter::class;
+ }
+
+ /** @noinspection PhpUndefinedMethodInspection */
+ $highlightedContent = $this->fixMarkup(explode("\n", $className::getInstance()->highlight($content)));
+
+ // show template
+ /** @noinspection PhpUndefinedMethodInspection */
+ WCF::getTPL()->assign([
+ 'lineNumbers' => $this->makeLineNumbers($content, $line),
+ 'startLineNumber' => $line,
+ 'content' => $highlightedContent,
+ 'highlighter' => $className::getInstance(),
+ 'filename' => $file,
+ 'lines' => substr_count($content, "\n") + 1
+ ]);
+
+ return WCF::getTPL()->fetch('codeMetaCode');
+ }
+
+ /**
+ * Returns a string with all line numbers
+ *
+ * @param string $code
+ * @param integer $start
+ * @param string $split
+ * @return string
+ */
+ protected function makeLineNumbers($code, $start, $split = "\n") {
+ $lines = explode($split, $code);
+
+ $lineNumbers = [];
+ $i = -1;
+ // find an unused codeID
+ do {
+ $codeID = mb_substr(StringUtil::getHash($code), 0, 6).(++$i ? '_'.$i : '');
+ }
+ while (isset(self::$codeIDs[$codeID]));
+
+ // mark codeID as used
+ self::$codeIDs[$codeID] = true;
+
+ for ($i = $start, $j = count($lines) + $start; $i < $j; $i++) {
+ $lineNumbers[$i] = 'codeLine_'.$i.'_'.$codeID;
+ }
+ return $lineNumbers;
+ }
+
+ /**
+ * Fixes markup that every line has proper number of opening and closing tags
+ *
+ * @param string[] $lines
+ * @return string[]
+ */
+ protected function fixMarkup(array $lines) {
+ static $spanRegex = null;
+ static $emptyTagRegex = null;
+ if ($spanRegex === null) {
+ $spanRegex = new Regex('(?:<span(?: class="(?:[^"])*")?>|</span>)');
+ $emptyTagRegex = new Regex('<span(?: class="(?:[^"])*")?></span>');
+ }
+
+ $openTags = [];
+ foreach ($lines as &$line) {
+ $spanRegex->match($line, true);
+ // open all tags again
+ $line = implode('', $openTags).$line;
+ $matches = $spanRegex->getMatches();
+
+ // parse opening and closing spans
+ foreach ($matches[0] as $match) {
+ if ($match === '</span>') array_pop($openTags);
+ else {
+ array_push($openTags, $match);
+ }
+ }
+
+ // close all tags
+ $line .= str_repeat('</span>', count($openTags));
+
+ // remove empty tags to avoid cluttering the output
+ $line = $emptyTagRegex->replace($line, '');
+ }
+ unset($line);
+
+ return $lines;
+ }
+}
$this->invokeHtmlNode(new HtmlOutputNodeWoltlabMention());
$this->invokeHtmlNode(new HtmlOutputNodeWoltlabColor());
$this->invokeHtmlNode(new HtmlOutputNodeWoltlabSize());
+ $this->invokeHtmlNode(new HtmlOutputNodeWoltlabSpoiler());
+ $this->invokeHtmlNode(new HtmlOutputNodePre());
}
}
--- /dev/null
+<?php
+namespace wcf\system\html\output\node;
+use wcf\system\application\ApplicationHandler;
+use wcf\system\html\node\AbstractHtmlNode;
+use wcf\system\html\node\HtmlNodeProcessor;
+use wcf\system\request\RouteHandler;
+use wcf\system\WCF;
+use wcf\util\StringUtil;
+
+/**
+ * TOOD documentation
+ * @since 3.0
+ */
+class HtmlOutputNodeWoltlabSpoiler extends AbstractHtmlNode {
+ protected $tagName = 'woltlab-spoiler';
+
+ /**
+ * @inheritDoc
+ */
+ public function process(array $elements, HtmlNodeProcessor $htmlNodeProcessor) {
+ /** @var \DOMElement $element */
+ foreach ($elements as $element) {
+ $nodeIdentifier = StringUtil::getRandomID();
+ $htmlNodeProcessor->addNodeData($this, $nodeIdentifier, [
+ 'label' => ($element->hasAttribute('data-label')) ? $element->getAttribute('data-label') : ''
+ ]);
+
+ $htmlNodeProcessor->renameTag($element, 'wcfNode-' . $nodeIdentifier);
+ }
+ }
+
+ public function replaceTag(array $data) {
+ WCF::getTPL()->assign([
+ 'buttonLabel' => $data['label']
+ ]);
+ return WCF::getTPL()->fetch('spoilerMetaCode');
+ }
+}
@include wcfFontHeadline;
}
}
+
+.codeBox {
+ background-color: $wcfContentBackground;
+ box-shadow: 0 0 3px rgba(0, 0, 0, .12), 0 1px 2px rgba(0, 0, 0, .24);
+ border-radius: 2px;
+ margin-top: 1em;
+ padding: 10px;
+
+ > div {
+ > ol {
+ margin-left: 3.4em !important;
+ position: relative;
+
+ &::before {
+ border-right: 1px solid $wcfContentBorderInner;
+ bottom: 0;
+ content: "";
+ position: absolute;
+ top: 0;
+ }
+
+ > li {
+ padding-left: 5px;
+ }
+ }
+ }
+}
+
+/* ############## Code Styles ############## */
+
+/* -- -- -- Code Box -- -- -- */
+
+.codeBox .hlQuotes {
+ color: red;
+}
+
+.codeBox .hlComments,
+.codeBox .hlOperators {
+ color: green;
+}
+
+.codeBox .hlKeywords1 {
+ color: blue;
+}
+
+.codeBox .hlKeywords2 {
+ color: darkred;
+}
+
+.codeBox .hlKeywords3 {
+ color: darkviolet;
+}
+
+.codeBox .hlKeywords4 {
+ color: darkgoldenrod;
+}
+
+.codeBox .hlKeywords5 {
+ color: crimson;
+}
+
+.codeBox .hlNumbers {
+ color: darkorange;
+}
+
+/* -- -- -- Code Highlighters -- -- -- */
+
+/* DIFF */
+
+.diffHighlighter .hlComments {
+ color: darkviolet;
+}
+
+.diffHighlighter .hlRemoved {
+ color: red;
+}
+
+.diffHighlighter .hlAdded {
+ color: green;
+}
+
+/* PHP */
+
+.phpHighlighter .hlKeywords2 {
+ color: green;
+}
+
+.phpHighlighter .hlComments {
+ color: darkgoldenrod;
+}
+
+/* CSS */
+
+.cssHighlighter .hlComments {
+ color: #236e26;
+}
+
+.cssHighlighter .hlColors {
+ color: #751116;
+}
+
+.cssHighlighter .hlNumbers,
+.sqlHighlighter .hlNumbers {
+ color: #1906fd;
+}
+
+.cssHighlighter .hlKeywords1 {
+ color: #87154f;
+}
+
+.cssHighlighter .hlKeywords2 {
+ color: #994509;
+}
+
+.cssHighlighter .hlKeywords3,
+.cssHighlighter .hlKeywords4 {
+ color: inherit;
+}
+
+/* SQL */
+
+.sqlHighlighter .hlKeywords1 {
+ color: #663821;
+}
+
+.sqlHighlighter .hlKeywords2 {
+ color: #871550;
+}
<category name="wcf.bbcode">
<item name="wcf.bbcode.code"><![CDATA[Code]]></item>
<item name="wcf.bbcode.code.bash.title"><![CDATA[Shell-Script]]></item>
- <item name="wcf.bbcode.code.brainfuck.title"><![CDATA[Brainfuck]]></item>
<item name="wcf.bbcode.code.c.title"><![CDATA[C]]></item>
<item name="wcf.bbcode.code.css.title"><![CDATA[CSS]]></item>
<item name="wcf.bbcode.code.diff.title"><![CDATA[Diff]]></item>
<category name="wcf.bbcode">
<item name="wcf.bbcode.code"><![CDATA[Code]]></item>
<item name="wcf.bbcode.code.bash.title"><![CDATA[Shell-Script]]></item>
- <item name="wcf.bbcode.code.brainfuck.title"><![CDATA[Brainfuck]]></item>
<item name="wcf.bbcode.code.c.title"><![CDATA[C]]></item>
<item name="wcf.bbcode.code.css.title"><![CDATA[CSS]]></item>
<item name="wcf.bbcode.code.diff.title"><![CDATA[Diff]]></item>