], 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}',
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
}
};
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));
}
};
*/
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);
}
};
});
--- /dev/null
+/**
+ * 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
&::before {
content: attr(data-display-value);
+ cursor: pointer;
display: block;
font-family: $wcfFontFamily;
margin-bottom: 20px;
-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); }
</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>
<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>
<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>
</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>
<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>
<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>