Overhauled code implementation for Redactor
authorAlexander Ebert <ebert@woltlab.com>
Tue, 14 Jun 2016 19:57:40 +0000 (21:57 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Tue, 14 Jun 2016 19:57:48 +0000 (21:57 +0200)
com.woltlab.wcf/templates/wysiwyg.tpl
wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabCode.js
wcfsetup/install/files/js/WoltLab/WCF/Event/Key.js
wcfsetup/install/files/js/WoltLab/WCF/Ui/Redactor/Code.js [new file with mode: 0644]
wcfsetup/install/files/style/bbcode/code.scss
wcfsetup/install/files/style/layout/global.scss
wcfsetup/install/lang/de.xml
wcfsetup/install/lang/en.xml

index 52bc64755c8dd598150e1bdc766364e58a508782..d27fdea03c5277699b1bac8bcc3130881ae8878d 100644 (file)
        ], function () {
                require(['Language', 'WoltLab/WCF/Ui/Redactor/Metacode'], function(Language, UiRedactorMetacode) {
                        Language.addObject({
+                               'wcf.editor.code.edit': '{lang}wcf.editor.code.edit{/lang}',
+                               'wcf.editor.code.file': '{lang}wcf.editor.code.file{/lang}',
+                               'wcf.editor.code.file.description': '{lang}wcf.editor.code.file.description{/lang}',
+                               'wcf.editor.code.highlighter': '{lang}wcf.editor.code.highlighter{/lang}',
+                               'wcf.editor.code.highlighter.description': '{lang}wcf.editor.code.highlighter.description{/lang}',
+                               'wcf.editor.code.line': '{lang}wcf.editor.code.line{/lang}',
+                               'wcf.editor.code.line.description': '{lang}wcf.editor.code.line.description{/lang}',
+                               'wcf.editor.code.title': '{lang __literal=true}wcf.editor.code.title{/lang}',
                                'wcf.editor.image.edit': '{lang}wcf.editor.image.edit{/lang}',
                                'wcf.editor.image.insert': '{lang}wcf.editor.image.insert{/lang}',
                                'wcf.editor.image.link': '{lang}wcf.editor.image.link{/lang}',
@@ -54,6 +62,8 @@
                        var buttons = [], buttonOptions = [], customButtons = [];
                        {include file='wysiwygToolbar'}
                        
+                       var highlighters = { {implode from=$__wcf->getBBCodeHandler()->getHighlighters() item=__highlighter}'{$__highlighter}': '{lang}wcf.bbcode.code.{@$__highlighter}.title{/lang}'{/implode} };
+                       
                        // TODO: Should the media stuff be here?
                        {include file='mediaJavaScript'}
                        
                                woltlab: {
                                        autosave: autosave,
                                        buttons: buttonOptions,
-                                       customButtons: customButtons
+                                       customButtons: customButtons,
+                                       highlighters: highlighters
                                }
                        };
                        
index a39af3d664fb4adc74b371c1e3dd4f7189ede83c..63d1a2e37f251990a59920a8de366244df4d4ecd 100644 (file)
@@ -3,25 +3,8 @@ $.Redactor.prototype.WoltLabCode = function() {
        
        return {
                init: function() {
-                       this.opts.activeButtonsStates.pre = 'code';
-                       
-                       require(['EventHandler'], (function (EventHandler) {
-                               EventHandler.add('com.woltlab.wcf.redactor2', 'bbcode_code_' + this.$element[0].id, (function(data) {
-                                       data.cancel = true;
-                                       
-                                       this.button.toggle({}, 'pre', 'func', 'block.format');
-                                       
-                                       var pre = this.selection.block();
-                                       if (pre && pre.nodeName === 'PRE') {
-                                               if (pre.textContent === '') {
-                                                       pre.textContent = '\u200B';
-                                               }
-                                               
-                                               if (elData(pre, 'display-value') === '') {
-                                                       elData(pre, 'display-value', 'TODO: source code');
-                                               }
-                                       }
-                               }).bind(this));
+                       require(['WoltLab/WCF/Ui/Redactor/Code'], (function (UiRedactorCode) {
+                               new UiRedactorCode(this);
                        }).bind(this));
                }
        };
index 3467e48e29c304c14dc7f1c75dafc4b4c4420686..a35a5da7466fc246f439e66d3b6e7960b91e4aa3 100644 (file)
@@ -80,6 +80,16 @@ define([], function() {
                 */
                Escape: function(event) {
                        return _isKey(event, 'Escape', 27);
+               },
+               
+               /**
+                * Returns true if pressed key equals 'Tab'.
+                * 
+                * @param       {Event}         event           event object
+                * @return      {boolean}
+                */
+               Tab: function(event) {
+                       return _isKey(event, 'Tab', 9);
                }
        };
 });
diff --git a/wcfsetup/install/files/js/WoltLab/WCF/Ui/Redactor/Code.js b/wcfsetup/install/files/js/WoltLab/WCF/Ui/Redactor/Code.js
new file mode 100644 (file)
index 0000000..ebdf434
--- /dev/null
@@ -0,0 +1,243 @@
+/**
+ * Provides helper functions to work with DOM nodes.
+ *
+ * @author      Alexander Ebert
+ * @copyright   2001-2016 WoltLab GmbH
+ * @license     GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module      WoltLab/WCF/Ui/Redactor/Code
+ */
+define(['EventHandler', 'EventKey', 'Language', 'StringUtil', 'Dom/Util', 'Ui/Dialog'], function (EventHandler, EventKey, Language, StringUtil, DomUtil, UiDialog) {
+       "use strict";
+       
+       var _headerHeight = 0;
+       
+       /**
+        * @param       {Object}        editor  editor instance
+        * @constructor
+        */
+       function UiRedactorCode(editor) { this.init(editor); }
+       UiRedactorCode.prototype = {
+               /**
+                * Initializes the source code management.
+                * 
+                * @param       {Object}        editor  editor instance
+                */
+               init: function(editor) {
+                       this._editor = editor;
+                       this._elementId = this._editor.$element[0].id;
+                       this._pre = null;
+                       
+                       EventHandler.add('com.woltlab.wcf.redactor2', 'bbcode_code_' + this._elementId, this._bbcodeCode.bind(this));
+                       EventHandler.add('com.woltlab.wcf.redactor2', 'observe_load_' + this._elementId, this._observeLoad.bind(this));
+                       
+                       // support for active button marking
+                       this._editor.opts.activeButtonsStates.pre = 'code';
+                       
+                       // static bind to ensure that removing works
+                       this._callbackEdit = this._edit.bind(this);
+                       
+                       // bind listeners on init
+                       this._observeLoad();
+               },
+               
+               /**
+                * Intercepts the insertion of `[code]` tags and uses a native `<pre>` instead.
+                * 
+                * @param       {Object}        data    event data
+                * @protected
+                */
+               _bbcodeCode: function(data) {
+                       data.cancel = true;
+                       
+                       this._editor.button.toggle({}, 'pre', 'func', 'block.format');
+                       
+                       var pre = this._editor.selection.block();
+                       if (pre && pre.nodeName === 'PRE') {
+                               if (pre.textContent === '') {
+                                       pre.textContent = '\u200B';
+                               }
+                               
+                               this._setTitle(pre);
+                               
+                               pre.removeEventListener(WCF_CLICK_EVENT, this._callbackEdit);
+                               pre.addEventListener(WCF_CLICK_EVENT, this._callbackEdit);
+                               
+                               // there must be some kind of element after the <pre>
+                               if (pre.nextElementSibling === null) {
+                                       var p = elCreate('p');
+                                       p.textContent = '\u200B';
+                                       pre.parentNode.appendChild(p);
+                               }
+                               
+                               this._editor.caret.after(pre);
+                       }
+               },
+               
+               /**
+                * Binds event listeners and sets quote title on both editor
+                * initialization and when switching back from code view.
+                * 
+                * @protected
+                */
+               _observeLoad: function() {
+                       elBySelAll('pre', this._editor.$editor[0], (function(pre) {
+                               pre.addEventListener(WCF_CLICK_EVENT, this._callbackEdit);
+                               this._setTitle(pre);
+                       }).bind(this));
+               },
+               
+               /**
+                * Opens the dialog overlay to edit the code's properties.
+                * 
+                * @param       {Event}         event           event object
+                * @protected
+                */
+               _edit: function(event) {
+                       var pre = event.currentTarget;
+                       
+                       if (_headerHeight === 0) {
+                               _headerHeight = ~~window.getComputedStyle(pre).paddingTop.replace(/px$/, '');
+                               
+                               var styles = window.getComputedStyle(pre, '::before');
+                               _headerHeight += ~~styles.paddingTop.replace(/px$/, '');
+                               _headerHeight += ~~styles.height.replace(/px$/, '');
+                               _headerHeight += ~~styles.paddingBottom.replace(/px$/, '');
+                       }
+                       
+                       // check if the click hit the header
+                       var offset = DomUtil.offset(pre);
+                       if (event.pageY > offset.top && event.pageY < (offset.top + _headerHeight)) {
+                               event.preventDefault();
+                               
+                               this._pre = pre;
+                               
+                               UiDialog.open(this);
+                       }
+               },
+               
+               /**
+                * Saves the changes to the code's properties.
+                * 
+                * @param       {Event}         event           event object
+                * @protected
+                */
+               _save: function(event) {
+                       event.preventDefault();
+                       
+                       var id = 'redactor-code-' + this._elementId;
+                       
+                       ['file', 'highlighter', 'line'].forEach((function (attr) {
+                               elData(this._pre, attr, elById(id + '-' + attr).value);
+                       }).bind(this));
+                       
+                       this._setTitle(this._pre);
+                       this._editor.caret.after(this._pre);
+                       
+                       UiDialog.close(this);
+               },
+               
+               /**
+                * Sets or updates the code's header title.
+                * 
+                * @param       {Element}       pre     code element
+                * @protected
+                */
+               _setTitle: function(pre) {
+                       var file = elData(pre, 'file'),
+                           highlighter = elData(pre, 'highlighter');
+                       
+                       //noinspection JSUnresolvedVariable
+                       highlighter = (this._editor.opts.woltlab.highlighters.hasOwnProperty(highlighter)) ? this._editor.opts.woltlab.highlighters[highlighter] : '';
+                       
+                       elData(pre, 'display-value', Language.get('wcf.editor.code.title', {
+                               file: file,
+                               highlighter: highlighter
+                       }));
+               },
+               
+               _dialogSetup: function() {
+                       var id = 'redactor-code-' + this._elementId,
+                           idButtonSave = id + '-button-save',
+                           idFile = id + '-file',
+                           idHighlighter = id + '-highlighter',
+                           idLine = id + '-line';
+                       
+                       return {
+                               id: id,
+                               options: {
+                                       onSetup: (function() {
+                                               elById(idButtonSave).addEventListener(WCF_CLICK_EVENT, this._save.bind(this));
+                                               
+                                               // set highlighters
+                                               var highlighters = '<option value="">' + Language.get('wcf.global.noSelection') + '</option>';
+                                               
+                                               var value, values = [];
+                                               //noinspection JSUnresolvedVariable
+                                               for (var highlighter in this._editor.opts.woltlab.highlighters) {
+                                                       //noinspection JSUnresolvedVariable
+                                                       if (this._editor.opts.woltlab.highlighters.hasOwnProperty(highlighter)) {
+                                                               //noinspection JSUnresolvedVariable
+                                                               values.push([highlighter, this._editor.opts.woltlab.highlighters[highlighter]]);
+                                                       }
+                                               }
+                                               
+                                               // sort by label
+                                               values.sort(function(a, b) {
+                                                       if (a[1] < b[1]) {
+                                                               return  -1;
+                                                       }
+                                                       else if (a[1] > b[1]) {
+                                                               return 1;
+                                                       }
+                                                       
+                                                       return 0;
+                                               });
+                                               
+                                               values.forEach((function(value) {
+                                                       highlighters += '<option value="' + value[0] + '">' + StringUtil.escapeHTML(value[1]) + '</option>';
+                                               }).bind(this));
+                                               
+                                               elById(idHighlighter).innerHTML = highlighters;
+                                       }).bind(this),
+                                       
+                                       onShow: (function() {
+                                               elById(idHighlighter).value = elData(this._pre, 'highlighter');
+                                               var line = elData(this._pre, 'line');
+                                               elById(idLine).value = (line === '') ? 1 : ~~line;
+                                               elById(idFile).value = elData(this._pre, 'file');
+                                       }).bind(this),
+                                       
+                                       title: Language.get('wcf.editor.code.edit')
+                               },
+                               source: '<div class="section">'
+                                       + '<dl>'
+                                               + '<dt><label for="' + idHighlighter + '">' + Language.get('wcf.editor.code.highlighter') + '</label></dt>'
+                                               + '<dd>'
+                                                       + '<select id="' + idHighlighter + '"></select>'
+                                                       + '<small>' + Language.get('wcf.editor.code.highlighter.description') + '</small>'
+                                               + '</dd>'
+                                       + '</dl>'
+                                       + '<dl>'
+                                               + '<dt><label for="' + idLine + '">' + Language.get('wcf.editor.code.line') + '</label></dt>'
+                                               + '<dd>'
+                                                       + '<input type="number" id="' + idLine + '" min="0" value="1" class="long">'
+                                                       + '<small>' + Language.get('wcf.editor.code.line.description') + '</small>'
+                                               + '</dd>'
+                                       + '</dl>'
+                                       + '<dl>'
+                                               + '<dt><label for="' + idFile + '">' + Language.get('wcf.editor.code.file') + '</label></dt>'
+                                               + '<dd>'
+                                                       + '<input type="text" id="' + idFile + '" class="long">'
+                                                       + '<small>' + Language.get('wcf.editor.code.file.description') + '</small>'
+                                               + '</dd>'
+                                       + '</dl>'
+                               + '</div>'
+                               + '<div class="formSubmit">'
+                                       + '<button id="' + idButtonSave + '" class="buttonPrimary">' + Language.get('wcf.global.button.save') + '</button>'
+                               + '</div>'
+                       };
+               }
+       };
+       
+       return UiRedactorCode;
+});
\ No newline at end of file
index 92e47e73a08057850a1838b5611464d195272ae3..eedcfa9d83ec4f1f102819cf5d43ba12b381f1fc 100644 (file)
@@ -11,6 +11,7 @@
        
        &::before {
                content: attr(data-display-value);
+               cursor: pointer;
                display: block;
                font-family: $wcfFontFamily;
                margin-bottom: 20px;
index 58c38075232a32847b3ef3c2d17e3d847b857c5b..c1ba6fc38d6d51b1db361f6fe94a63cab2eaba49 100644 (file)
        -webkit-filter: grayscale(1);
 }
 
+.monospace {
+       font-family: Consolas, 'Courier New', monospace !important;
+}
+
 /* boxes with an image */
 .box16 { @include box(16px, 5px); }
 .box24 { @include box(24px, 8px); }
index e2ea991c077eb458f23a26df82711593c40e0a54..b3ee9edaa9878992cc5fa9f02fba30701d7a8413 100644 (file)
@@ -1776,34 +1776,24 @@ Erlaubte Dateiendungen: {', '|implode:$attachmentHandler->getFormattedAllowedExt
        </category>
        
        <category name="wcf.bbcode">
-               <item name="wcf.bbcode.code"><![CDATA[Quellcode]]></item>
+               <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-Quellcode]]></item>
-               <item name="wcf.bbcode.code.c.title"><![CDATA[C-Quellcode]]></item>
-               <item name="wcf.bbcode.code.css.title"><![CDATA[CSS-Quellcode]]></item>
-               <item name="wcf.bbcode.code.diff.title"><![CDATA[Unterschiede-Datei]]></item>
-               <item name="wcf.bbcode.code.edit"><![CDATA[Quellcode bearbeiten]]></item>
-               <item name="wcf.bbcode.code.filename"><![CDATA[Dateiname]]></item>
-               <item name="wcf.bbcode.code.filename.description"><![CDATA[Optional: Legen Sie einen anzuzeigenden Dateinamen fest.]]></item>
-               <item name="wcf.bbcode.code.highlighter"><![CDATA[Syntax-Hervorherbung]]></item>
-               <item name="wcf.bbcode.code.highlighter.description"><![CDATA[Die farbliche Hervorherbung wird im Editor nicht angezeigt.]]></item>
-               <item name="wcf.bbcode.code.highlighter.none"><![CDATA[(Keine Hervorhebung)]]></item>
-               <item name="wcf.bbcode.code.html.title"><![CDATA[HTML-Quellcode]]></item>
-               <item name="wcf.bbcode.code.insert"><![CDATA[Quellcode einfügen]]></item>
-               <item name="wcf.bbcode.code.java.title"><![CDATA[Java-Quellcode]]></item>
-               <item name="wcf.bbcode.code.js.title"><![CDATA[JavaScript-Quellcode]]></item>
-               <item name="wcf.bbcode.code.lineNumber"><![CDATA[Start-Zeilennummer]]></item>
-               <item name="wcf.bbcode.code.lineNumber.description"><![CDATA[Optional: Legen Sie den Wert fest, ab dem die Zeilennummierung startet.]]></item>
-               <item name="wcf.bbcode.code.perl.title"><![CDATA[Perl-Quellcode]]></item>
-               <item name="wcf.bbcode.code.php.title"><![CDATA[PHP-Quellcode]]></item>
-               <item name="wcf.bbcode.code.plain.title"><![CDATA[Quellcode]]></item>
-               <item name="wcf.bbcode.code.sql.title"><![CDATA[SQL-Abfrage]]></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>
+               <item name="wcf.bbcode.code.html.title"><![CDATA[HTML]]></item>
+               <item name="wcf.bbcode.code.java.title"><![CDATA[Java]]></item>
+               <item name="wcf.bbcode.code.js.title"><![CDATA[JavaScript]]></item>
+               <item name="wcf.bbcode.code.perl.title"><![CDATA[Perl]]></item>
+               <item name="wcf.bbcode.code.php.title"><![CDATA[PHP]]></item>
+               <item name="wcf.bbcode.code.plain.title"><![CDATA[Code]]></item>
+               <item name="wcf.bbcode.code.sql.title"><![CDATA[SQL]]></item>
                <item name="wcf.bbcode.code.text"><![CDATA[{@$highlighterTitle} ({#$lines} Zeile{if $lines != 1}n{/if})]]></item>
-               <item name="wcf.bbcode.code.python.title"><![CDATA[Python-Quellcode]]></item>
-               <item name="wcf.bbcode.code.settings"><![CDATA[Einstellungen]]></item>
-               <item name="wcf.bbcode.code.tex.title"><![CDATA[TeX-Quellcode]]></item>
-               <item name="wcf.bbcode.code.tpl.title"><![CDATA[Smarty-Template]]></item>
-               <item name="wcf.bbcode.code.xml.title"><![CDATA[XML-Quellcode]]></item>
+               <item name="wcf.bbcode.code.python.title"><![CDATA[Python]]></item>
+               <item name="wcf.bbcode.code.tex.title"><![CDATA[TeX]]></item>
+               <item name="wcf.bbcode.code.tpl.title"><![CDATA[Smarty]]></item>
+               <item name="wcf.bbcode.code.xml.title"><![CDATA[XML]]></item>
                <item name="wcf.bbcode.image.source"><![CDATA[Bild-Link]]></item>
                <item name="wcf.bbcode.quote.delete"><![CDATA[Zitat löschen]]></item>
                <item name="wcf.bbcode.quote.edit"><![CDATA[Zitat bearbeiten]]></item>
@@ -2127,6 +2117,7 @@ Fehler sind beispielsweise:
        <category name="wcf.editor">
                <item name="wcf.editor.button.alignment"><![CDATA[Ausrichtung]]></item>
                <item name="wcf.editor.button.bold"><![CDATA[Fett]]></item>
+               <item name="wcf.editor.button.code"><![CDATA[Code]]></item>
                <item name="wcf.editor.button.color"><![CDATA[Schriftfarbe]]></item>
                <item name="wcf.editor.button.html"><![CDATA[HTML]]></item>
                <item name="wcf.editor.button.image"><![CDATA[Bild]]></item>
@@ -2142,6 +2133,15 @@ Fehler sind beispielsweise:
                <item name="wcf.editor.button.table"><![CDATA[Tabelle]]></item>
                <item name="wcf.editor.button.underline"><![CDATA[Unterstrichen]]></item>
                
+               <item name="wcf.editor.code.edit"><![CDATA[Code bearbeiten]]></item>
+               <item name="wcf.editor.code.file"><![CDATA[Dateiname]]></item>
+               <item name="wcf.editor.code.file.description"><![CDATA[Optional: Legen Sie einen anzuzeigenden Dateinamen fest.]]></item>
+               <item name="wcf.editor.code.highlighter"><![CDATA[Syntax-Hervorhebung]]></item>
+               <item name="wcf.editor.code.highlighter.description"><![CDATA[Die farbliche Hervorherbung wird im Editor nicht angezeigt.]]></item>
+               <item name="wcf.editor.code.line"><![CDATA[Start-Zeilennummer]]></item>
+               <item name="wcf.editor.code.line.description"><![CDATA[Optional: Legen Sie den Wert fest, ab dem die Zeilennummierung startet.]]></item>
+               <item name="wcf.editor.code.title"><![CDATA[{if $highlighter}{$highlighter}{else}Quellcode{/if}{if $file} - {$file}{/if}]]></item>
+               
                <item name="wcf.editor.image.edit"><![CDATA[Bild bearbeiten]]></item>
                <item name="wcf.editor.image.insert"><![CDATA[Bild einfügen]]></item>
                <item name="wcf.editor.image.link"><![CDATA[Verlinkung]]></item>
index d9536e50b561faa1df18f3cce3a06e18db83fcfe..2bc5cc9b1046b77b5c8b0b387bdb137732fc9d9c 100644 (file)
@@ -1783,34 +1783,24 @@ Allowed extensions: {', '|implode:$attachmentHandler->getFormattedAllowedExtensi
        </category>
        
        <category name="wcf.bbcode">
-               <item name="wcf.bbcode.code"><![CDATA[Source Code]]></item>
+               <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 Source Code]]></item>
-               <item name="wcf.bbcode.code.c.title"><![CDATA[C Source Code]]></item>
-               <item name="wcf.bbcode.code.css.title"><![CDATA[CSS Source Code]]></item>
-               <item name="wcf.bbcode.code.diff.title"><![CDATA[Difference-File]]></item>
-               <item name="wcf.bbcode.code.edit"><![CDATA[Edit Source Code]]></item>
-               <item name="wcf.bbcode.code.filename"><![CDATA[Filename]]></item>
-               <item name="wcf.bbcode.code.filename.description"><![CDATA[Optional: Specify the displayed filename.]]></item>
-               <item name="wcf.bbcode.code.highlighter"><![CDATA[Syntax Highlighting]]></item>
-               <item name="wcf.bbcode.code.highlighter.description"><![CDATA[Highlighting is not displayed within the editor.]]></item>
-               <item name="wcf.bbcode.code.highlighter.none"><![CDATA[(No Highlighting)]]></item>
-               <item name="wcf.bbcode.code.html.title"><![CDATA[HTML Source Code]]></item>
-               <item name="wcf.bbcode.code.insert"><![CDATA[Insert Source Code]]></item>
-               <item name="wcf.bbcode.code.java.title"><![CDATA[Java Source Code]]></item>
-               <item name="wcf.bbcode.code.js.title"><![CDATA[JavaScript Source Code]]></item>
-               <item name="wcf.bbcode.code.lineNumber"><![CDATA[Start Line Number]]></item>
-               <item name="wcf.bbcode.code.lineNumber.description"><![CDATA[Optional: Specify the start for line enumeration.]]></item>
-               <item name="wcf.bbcode.code.perl.title"><![CDATA[Perl Source Code]]></item>
-               <item name="wcf.bbcode.code.php.title"><![CDATA[PHP Source Code]]></item>
-               <item name="wcf.bbcode.code.plain.title"><![CDATA[Source Code]]></item>
-               <item name="wcf.bbcode.code.python.title"><![CDATA[Python Source Code]]></item>
-               <item name="wcf.bbcode.code.settings"><![CDATA[Settings]]></item>
-               <item name="wcf.bbcode.code.sql.title"><![CDATA[SQL-Query]]></item>
-               <item name="wcf.bbcode.code.tex.title"><![CDATA[TeX Source Code]]></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>
+               <item name="wcf.bbcode.code.html.title"><![CDATA[HTML]]></item>
+               <item name="wcf.bbcode.code.java.title"><![CDATA[Java]]></item>
+               <item name="wcf.bbcode.code.js.title"><![CDATA[JavaScript]]></item>
+               <item name="wcf.bbcode.code.perl.title"><![CDATA[Perl]]></item>
+               <item name="wcf.bbcode.code.php.title"><![CDATA[PHP]]></item>
+               <item name="wcf.bbcode.code.plain.title"><![CDATA[Code]]></item>
+               <item name="wcf.bbcode.code.python.title"><![CDATA[Python]]></item>
+               <item name="wcf.bbcode.code.sql.title"><![CDATA[SQL]]></item>
+               <item name="wcf.bbcode.code.tex.title"><![CDATA[TeX]]></item>
                <item name="wcf.bbcode.code.text"><![CDATA[{@$highlighterTitle} ({#$lines} line{if $lines != 1}s{/if})]]></item>
-               <item name="wcf.bbcode.code.tpl.title"><![CDATA[Smarty-Template]]></item>
-               <item name="wcf.bbcode.code.xml.title"><![CDATA[XML Source Code]]></item>
+               <item name="wcf.bbcode.code.tpl.title"><![CDATA[Smarty]]></item>
+               <item name="wcf.bbcode.code.xml.title"><![CDATA[XML]]></item>
                <item name="wcf.bbcode.image.source"><![CDATA[Image Link]]></item>
                <item name="wcf.bbcode.quote.delete"><![CDATA[Delete Quote]]></item>
                <item name="wcf.bbcode.quote.edit"><![CDATA[Edit Quote]]></item>
@@ -2138,6 +2128,7 @@ Errors are:
        <category name="wcf.editor">
                <item name="wcf.editor.button.alignment"><![CDATA[Alignment]]></item>
                <item name="wcf.editor.button.bold"><![CDATA[Bold]]></item>
+               <item name="wcf.editor.button.code"><![CDATA[Code]]></item>
                <item name="wcf.editor.button.color"><![CDATA[Font Color]]></item>
                <item name="wcf.editor.button.html"><![CDATA[HTML]]></item>
                <item name="wcf.editor.button.image"><![CDATA[Image]]></item>
@@ -2153,6 +2144,15 @@ Errors are:
                <item name="wcf.editor.button.table"><![CDATA[Table]]></item>
                <item name="wcf.editor.button.underline"><![CDATA[Underline]]></item>
                
+               <item name="wcf.editor.code.edit"><![CDATA[Edit Code]]></item>
+               <item name="wcf.editor.code.file"><![CDATA[Filename]]></item>
+               <item name="wcf.editor.code.file.description"><![CDATA[Optional: Specify the displayed filename.]]></item>
+               <item name="wcf.editor.code.highlighter"><![CDATA[Syntax Highlighting]]></item>
+               <item name="wcf.editor.code.highlighter.description"><![CDATA[Highlighting is not displayed within the editor.]]></item>
+               <item name="wcf.editor.code.line"><![CDATA[Start Line Number]]></item>
+               <item name="wcf.editor.code.line.description"><![CDATA[Optional: Specify the start for line enumeration.]]></item>
+               <item name="wcf.editor.code.title"><![CDATA[{if $highlighter}{$highlighter}{else}Code{/if}{if $file} - {$file}{/if}]]></item>
+               
                <item name="wcf.editor.image.edit"><![CDATA[Edit Image]]></item>
                <item name="wcf.editor.image.insert"><![CDATA[Insert Image]]></item>
                <item name="wcf.editor.image.link"><![CDATA[Link]]></item>