Fixed bug #11839: t3editor doesn't have an API for using at other places
authorTobias Liebig <mail@etobi.de>
Thu, 1 Apr 2010 16:00:51 +0000 (16:00 +0000)
committerTobias Liebig <mail@etobi.de>
Thu, 1 Apr 2010 16:00:51 +0000 (16:00 +0000)
git-svn-id: https://svn.typo3.org/TYPO3v4/Core/trunk@7234 709f56b5-9817-0410-a4d7-c38de5d9e867

74 files changed:
ChangeLog
typo3/sysext/t3editor/class.tx_t3editor.php [deleted file]
typo3/sysext/t3editor/classes/class.tx_t3editor.php [new file with mode: 0644]
typo3/sysext/t3editor/classes/class.tx_t3editor_hooks_tstemplateinfo.php [new file with mode: 0644]
typo3/sysext/t3editor/classes/ts_codecompletion/class.tx_t3editor_codecompletion.php [new file with mode: 0644]
typo3/sysext/t3editor/classes/ts_codecompletion/class.tx_t3editor_tsrefloader.php [new file with mode: 0644]
typo3/sysext/t3editor/css/t3editor.css [deleted file]
typo3/sysext/t3editor/css/t3editor_inner.css [deleted file]
typo3/sysext/t3editor/ext_emconf.php
typo3/sysext/t3editor/ext_localconf.php
typo3/sysext/t3editor/ext_tables.php
typo3/sysext/t3editor/jslib/codemirror/LICENSE [deleted file]
typo3/sysext/t3editor/jslib/codemirror/README [deleted file]
typo3/sysext/t3editor/jslib/codemirror/codemirror.js [deleted file]
typo3/sysext/t3editor/jslib/codemirror/editor.js [deleted file]
typo3/sysext/t3editor/jslib/codemirror/mirrorframe.js [deleted file]
typo3/sysext/t3editor/jslib/codemirror/parsecss.js [deleted file]
typo3/sysext/t3editor/jslib/codemirror/parsehtmlmixed.js [deleted file]
typo3/sysext/t3editor/jslib/codemirror/parsejavascript.js [deleted file]
typo3/sysext/t3editor/jslib/codemirror/parsesparql.js [deleted file]
typo3/sysext/t3editor/jslib/codemirror/parsetyposcript.js [deleted file]
typo3/sysext/t3editor/jslib/codemirror/parsexml.js [deleted file]
typo3/sysext/t3editor/jslib/codemirror/select.js [deleted file]
typo3/sysext/t3editor/jslib/codemirror/stringstream.js [deleted file]
typo3/sysext/t3editor/jslib/codemirror/tokenize.js [deleted file]
typo3/sysext/t3editor/jslib/codemirror/tokenizejavascript.js [deleted file]
typo3/sysext/t3editor/jslib/codemirror/tokenizetyposcript.js [deleted file]
typo3/sysext/t3editor/jslib/codemirror/undo.js [deleted file]
typo3/sysext/t3editor/jslib/codemirror/util.js [deleted file]
typo3/sysext/t3editor/jslib/t3editor.js [deleted file]
typo3/sysext/t3editor/jslib/ts_codecompletion/completionresult.js [deleted file]
typo3/sysext/t3editor/jslib/ts_codecompletion/descriptionPlugin.js [deleted file]
typo3/sysext/t3editor/jslib/ts_codecompletion/tscodecompletion.js [deleted file]
typo3/sysext/t3editor/jslib/ts_codecompletion/tsparser.js [deleted file]
typo3/sysext/t3editor/jslib/ts_codecompletion/tsref.js [deleted file]
typo3/sysext/t3editor/lib/ts_codecompletion/class.tx_t3editor_codecompletion.php [deleted file]
typo3/sysext/t3editor/lib/ts_codecompletion/class.tx_t3editor_tsrefloader.php [deleted file]
typo3/sysext/t3editor/res/css/csscolors.css [new file with mode: 0644]
typo3/sysext/t3editor/res/css/jscolors.css [new file with mode: 0644]
typo3/sysext/t3editor/res/css/sparqlcolors.css [new file with mode: 0644]
typo3/sysext/t3editor/res/css/t3editor.css [new file with mode: 0644]
typo3/sysext/t3editor/res/css/t3editor_inner.css [new file with mode: 0644]
typo3/sysext/t3editor/res/css/typoscriptcolors.css [new file with mode: 0644]
typo3/sysext/t3editor/res/css/xmlcolors.css [new file with mode: 0644]
typo3/sysext/t3editor/res/jslib/codemirror/LICENSE [new file with mode: 0644]
typo3/sysext/t3editor/res/jslib/codemirror/README [new file with mode: 0644]
typo3/sysext/t3editor/res/jslib/codemirror/codemirror.js [new file with mode: 0644]
typo3/sysext/t3editor/res/jslib/codemirror/editor.js [new file with mode: 0644]
typo3/sysext/t3editor/res/jslib/codemirror/highlight.js [new file with mode: 0644]
typo3/sysext/t3editor/res/jslib/codemirror/mirrorframe.js [new file with mode: 0644]
typo3/sysext/t3editor/res/jslib/codemirror/parsecss.js [new file with mode: 0644]
typo3/sysext/t3editor/res/jslib/codemirror/parsedummy.js [new file with mode: 0644]
typo3/sysext/t3editor/res/jslib/codemirror/parsehtmlmixed.js [new file with mode: 0644]
typo3/sysext/t3editor/res/jslib/codemirror/parsejavascript.js [new file with mode: 0644]
typo3/sysext/t3editor/res/jslib/codemirror/parsesparql.js [new file with mode: 0644]
typo3/sysext/t3editor/res/jslib/codemirror/parsetyposcript.js [new file with mode: 0644]
typo3/sysext/t3editor/res/jslib/codemirror/parsexml.js [new file with mode: 0644]
typo3/sysext/t3editor/res/jslib/codemirror/select.js [new file with mode: 0644]
typo3/sysext/t3editor/res/jslib/codemirror/stringstream.js [new file with mode: 0644]
typo3/sysext/t3editor/res/jslib/codemirror/tokenize.js [new file with mode: 0644]
typo3/sysext/t3editor/res/jslib/codemirror/tokenizejavascript.js [new file with mode: 0644]
typo3/sysext/t3editor/res/jslib/codemirror/tokenizetyposcript.js [new file with mode: 0644]
typo3/sysext/t3editor/res/jslib/codemirror/undo.js [new file with mode: 0644]
typo3/sysext/t3editor/res/jslib/codemirror/util.js [new file with mode: 0644]
typo3/sysext/t3editor/res/jslib/t3editor.js [new file with mode: 0644]
typo3/sysext/t3editor/res/jslib/ts_codecompletion/completionresult.js [new file with mode: 0644]
typo3/sysext/t3editor/res/jslib/ts_codecompletion/descriptionPlugin.js [new file with mode: 0644]
typo3/sysext/t3editor/res/jslib/ts_codecompletion/tscodecompletion.js [new file with mode: 0644]
typo3/sysext/t3editor/res/jslib/ts_codecompletion/tsparser.js [new file with mode: 0644]
typo3/sysext/t3editor/res/jslib/ts_codecompletion/tsref.js [new file with mode: 0644]
typo3/sysext/t3editor/res/jslib/tx_tstemplateinfo/tx_tstemplateinfo.js [new file with mode: 0644]
typo3/sysext/t3editor/res/templates/t3editor.html [new file with mode: 0644]
typo3/sysext/t3editor/res/tsref/tsref.xml [new file with mode: 0644]
typo3/sysext/t3editor/tsref/tsref.xml [deleted file]

index 67ab563..9a57516 100755 (executable)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,7 @@
 2010-04-01  Tobias Liebig  <mail_typo3@etobi.de>
 
        * Fixed bug #13557: t3editor/codecompletion: add new typoscript properties and update tsref descriptions
+       * Fixed bug #11839: t3editor doesn't have an API for using at other places
 
 2010-04-01  Steffen Kamper  <info@sk-typo3.de>
 
diff --git a/typo3/sysext/t3editor/class.tx_t3editor.php b/typo3/sysext/t3editor/class.tx_t3editor.php
deleted file mode 100755 (executable)
index 790aca0..0000000
+++ /dev/null
@@ -1,512 +0,0 @@
-<?php
-/***************************************************************
-*  Copyright notice
-*
-*  (c) 2007-2009 Tobias Liebig <mail_typo3@etobi.de>
-*  All rights reserved
-*
-*  This script is part of the TYPO3 project. The TYPO3 project is
-*  free software; you can redistribute it and/or modify
-*  it under the terms of the GNU General Public License as published by
-*  the Free Software Foundation; either version 2 of the License, or
-*  (at your option) any later version.
-*
-*  The GNU General Public License can be found at
-*  http://www.gnu.org/copyleft/gpl.html.
-*  A copy is found in the textfile GPL.txt and important notices to the license
-*  from the author is found in LICENSE.txt distributed with these scripts.
-*
-*
-*  This script is distributed in the hope that it will be useful,
-*  but WITHOUT ANY WARRANTY; without even the implied warranty of
-*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-*  GNU General Public License for more details.
-*
-*  This copyright notice MUST APPEAR in all copies of the script!
-***************************************************************/
-/**
- * [CLASS/FUNCTION INDEX of SCRIPT]
- *
- *
- *
- *   47: class tx_t3editor
- *   85:     public function __construct()
- *  117:     public function getJavascriptCode()
- *  162:     public function getCodeEditor($name, $class='', $content='', $additionalParams='', $alt='')
- *
- * TOTAL FUNCTIONS: 3
- * (This index is automatically created/updated by the extension "extdeveval")
- *
- */
-
-/**
- * Provides a javascript-driven code editor with syntax highlighting for TS, HTML, CSS and more
- *
- * @author     Tobias Liebig <mail_typo3@etobi.de>
- */
-
-$GLOBALS['LANG']->includeLLFile('EXT:t3editor/locallang.xml');
-
-class tx_t3editor {
-
-       /**
-        * path to the main javascript-file
-        *
-        * @var string
-        */
-       protected $filepathEditorlib;
-
-       /**
-        * path to the main stylesheet
-        *
-        * @TODO: make it configurable
-        *
-        * @var string
-        */
-       protected $filepathEditorcss;
-
-       /**
-        * counts the editors on the current page
-        *
-        * @var int
-        */
-       protected $editorCounter;
-
-       /**
-        * flag to enable the t3editor
-        *
-        * @var bool
-        */
-       public $isEnabled;
-
-       /**
-        * Creates a new instance of the class
-        *
-        * @return      void
-        */
-       public function __construct() {
-
-               $this->filepathEditorlib = 'jslib/t3editor.js';
-               $this->filepathEditorcss = 'css/t3editor.css';
-               $this->editorCounter     = 0;
-               $this->isEnabled         = true; //TODO add a method to switch to false and turn off the editor completly
-
-                       // check BE user settings
-                       //TODO give $state a more descriptive name / state of/for what?
-               $state = t3lib_div::_GP('t3editor_disableEditor') == 'true' ? true : $GLOBALS['BE_USER']->uc['disableT3Editor'];
-               $this->setBEUCdisableT3Editor($state);
-
-                       // disable pmktextarea to avoid conflicts (thanks Peter Klein for this suggestion)
-               $GLOBALS["BE_USER"]->uc['disablePMKTextarea'] = 1;
-       }
-
-       /**
-        * Sets editor enabled/disabled state
-        *
-        * @param       boolean         $state  <code>true</code> if editor is disabled
-        * @return      void
-        */
-       public function setBEUCdisableT3Editor($state) { //TODO better descriptive name for $state
-               if ($GLOBALS['BE_USER']->uc['disableT3Editor'] != $state) {
-                       $GLOBALS['BE_USER']->uc['disableT3Editor'] = $state;
-
-                       $GLOBALS['BE_USER']->writeUC();
-               }
-       }
-
-       /**
-        * Retrieves JavaScript code for editor
-        *
-        * @param       template        $doc
-        * @return      string          JavaScript code
-        */
-       public function getJavascriptCode($doc) {
-               $code = ''; // TODO find a more descriptive name (low prio)
-
-               if ($this->isEnabled) {
-
-                       $path_t3e = t3lib_extmgm::extRelPath('t3editor');
-
-                               // include needed javascript-frameworks
-                       /** @var $pageRenderer t3lib_PageRenderer */
-                       $pageRenderer = $doc->getPageRenderer();
-                       $pageRenderer->loadPrototype();
-                       $pageRenderer->loadScriptaculous();
-
-                               // include editor-css
-                       $code.= '<link href="' .
-                               $GLOBALS['BACK_PATH'] .
-                               t3lib_extmgm::extRelPath('t3editor') .
-                               $this->filepathEditorcss .
-                               '" type="text/css" rel="stylesheet" />';
-
-                               // include editor-js-lib
-                       $doc->loadJavascriptLib($path_t3e . 'jslib/codemirror/codemirror.js');
-                       $doc->loadJavascriptLib($path_t3e . 'jslib/t3editor.js');
-
-                       $doc->loadJavascriptLib($path_t3e . 'jslib/ts_codecompletion/tsref.js');
-                       $doc->loadJavascriptLib($path_t3e . 'jslib/ts_codecompletion/completionresult.js');
-                       $doc->loadJavascriptLib($path_t3e . 'jslib/ts_codecompletion/tsparser.js');
-                       $doc->loadJavascriptLib($path_t3e . 'jslib/ts_codecompletion/tscodecompletion.js');
-
-                       // set correct path to the editor
-
-                       $code.= t3lib_div::wrapJS(
-                               'var T3editor = T3editor || {};' .
-                               'T3editor.lang = ' . json_encode($this->getJavaScriptLabels()) .';' .
-                               // TODO namespace all js vars (PATH_t3e, URL_typo3, ...)
-                               'var PATH_t3e = "' . $GLOBALS['BACK_PATH'] . t3lib_extmgm::extRelPath('t3editor') . '"; ' .
-                               'var URL_typo3 = "' . htmlspecialchars(t3lib_div::getIndpEnv('TYPO3_SITE_URL') . TYPO3_mainDir) . '"; '
-                       );
-               }
-
-               return $code;
-       }
-
-       /**
-        * Gets the labels to be used in JavaScript in the Ext JS interface.
-        * TODO this method is copied from EXT:Recycler, maybe this should be refactored into a helper class
-        *
-        * @return      array           The labels to be used in JavaScript
-        */
-       protected function getJavaScriptLabels() {
-               $javaScriptLabels = $this->getJavaScriptLabelsFromLocallang('js.', 'label_');
-
-                       // Convert labels back to UTF-8 since json_encode() only works with UTF-8:
-               if ($GLOBALS['LANG']->charSet !== 'utf-8') {
-                       $GLOBALS['LANG']->csConvObj->convArray($javaScriptLabels, $GLOBALS['LANG']->charSet, 'utf-8');
-               }
-
-               return $javaScriptLabels;
-       }
-
-       /**
-        * Gets labels to be used in JavaScript fetched from the current locallang file.
-        * TODO this method is copied from EXT:Recycler, maybe this should be refactored into a helper class
-        *
-        * @param       string          $selectionPrefix: Prefix to select the correct labels (default: 'js.')
-        * @param       string          $stripFromSelectionName: Sub-prefix to be removed from label names in the result (default: '')
-        * @return      array           Lables to be used in JavaScript of the current locallang file
-        * @todo        Check, whether this method can be moved in a generic way to $GLOBALS['LANG']
-        */
-       protected function getJavaScriptLabelsFromLocallang($selectionPrefix = 'js.', $stripFromSelectionName = '') {
-               $extraction = array();
-               $labels = array_merge(
-                       (array)$GLOBALS['LOCAL_LANG']['default'],
-                       (array)$GLOBALS['LOCAL_LANG'][$GLOBALS['LANG']->lang]
-               );
-                       // Regular expression to strip the selection prefix and possibly something from the label name:
-               $labelPattern = '#^' . preg_quote($selectionPrefix, '#') . '(' . preg_quote($stripFromSelectionName, '#') . ')?#';
-                       // Iterate throuh all locallang lables:
-               foreach ($labels as $label => $value) {
-                       if (strpos($label, $selectionPrefix) === 0) {
-                               $key = preg_replace($labelPattern, '', $label);
-                               $extraction[$key] = $value;
-                       }
-               }
-               return $extraction;
-       }
-
-       /**
-        * Generates HTML with code editor
-        *
-        * @param       string          $name   Name attribute of HTML tag
-        * @param       string          $class  Class attribute of HTML tag
-        * @param       string          $content        Content of the editor
-        * @param       string          $additionalParams       Any additional editor parameters
-        * @param       string          $alt    Alt attribute
-        * @return      string          Generated HTML code for editor
-        */
-       public function getCodeEditor($name, $class='', $content='', $additionalParams='', $alt='', array $hiddenfields = array()) {
-               $code = '';
-
-               if ($this->isEnabled) {
-                       $this->editorCounter++;
-
-                       $class .= ' t3editor';
-                       if (!empty($alt)) {
-                               $alt = ' alt="' . $alt . '"';
-                       }
-
-                       $code .= '<div>' .
-                               '<textarea id="t3editor_' . $this->editorCounter . '" ' .
-                               'name="' . $name . '" ' .
-                               'class="' . $class . '" ' .
-                               $additionalParams . ' ' .
-                               $alt . '>' .
-                               $content .
-                               '</textarea></div>';
-
-                       $checked = $GLOBALS['BE_USER']->uc['disableT3Editor'] ? 'checked="checked"' : '';
-
-                       $code .= '<br /><br />' .
-                               '<input type="checkbox" ' .
-                               'class="checkbox" ' .
-                               'onclick="t3editor_toggleEditor(this);" ' .
-                               'name="t3editor_disableEditor" ' .
-                               'value="true" ' .
-                               'id="t3editor_disableEditor_' . $this->editorCounter.'_checkbox" ' .
-                               $checked.' />&nbsp;' .
-                               '<label for="t3editor_disableEditor_' . $this->editorCounter . '_checkbox">' .
-                               $GLOBALS['LANG']->getLL('deactivate') .
-                               '</label>' .
-                               '<br /><br />';
-
-                       if (count($hiddenfields)) {
-                               foreach ($hiddenfields as $name => $value) {
-                                       $code.= '<input type="hidden" ' .
-                                               'name="' . $name . '" ' .
-                                               'value="' . $value .
-                                               '" />';
-                               }
-                       }
-
-               } else {
-                       // fallback
-                       if (!empty($class)) {
-                               $class = 'class="' . $class . '" ';
-                       }
-
-                       $code .= '<textarea name="' . $name . '" ' .
-                               $class . $additionalParams.'>' .
-                               $content . '</textarea>';
-               }
-
-               return $code;
-       }
-
-
-       public function makeGlobalEditorInstance() {
-               if (!is_object($GLOBALS['T3_VAR']['t3editorObj'])) {
-                       $GLOBALS['T3_VAR']['t3editorObj'] = t3lib_div::getUserObj('EXT:t3editor/class.tx_t3editor.php:&tx_t3editor');
-               }
-       }
-
-       /**
-        * Hook-function: inject t3editor JavaScript code before the page is compiled
-        * called in typo3/template.php:startPage
-        *
-        * @param array $parameters
-        * @param template $pObj
-        */
-       public function preStartPageHook($parameters, $pObj) {
-               // enable editor in Template-Modul
-               if (preg_match('/sysext\/tstemplate\/ts\/index\.php/', $_SERVER['SCRIPT_NAME'])) {
-
-                       tx_t3editor::makeGlobalEditorInstance();
-
-                       // insert javascript code in document header
-                       $pObj->JScode .= $GLOBALS['T3_VAR']['t3editorObj']->getJavascriptCode($pObj);
-               }
-       }
-
-
-       /**
-        * Hook-function:
-        * called in typo3/sysext/tstemplate_info/class.tx_tstemplateinfo.php
-        *
-        * @param array $parameters
-        * @param tx_tstemplateinfo $pObj
-        */
-       public function postOutputProcessingHook($parameters, $pObj) {
-               tx_t3editor::makeGlobalEditorInstance();
-               if (!$GLOBALS['T3_VAR']['t3editorObj']->isEnabled) {
-                       return;
-               }
-
-               // Template Constants
-               if ($parameters['e']['constants']) {
-                       $attributes = 'rows="' . $parameters['numberOfRows'] . '" ' .
-                               'wrap="off" ' .
-                               $pObj->pObj->doc->formWidthText(48, 'width:98%;height:60%', 'off');
-
-                       $title = $GLOBALS['LANG']->getLL('template') . ' ' .
-                               htmlspecialchars($parameters['tplRow']['title']) .
-                               $GLOBALS['LANG']->getLL('delimiter') . ' ' .
-                               $GLOBALS['LANG']->getLL('constants');
-
-                       $outCode = $GLOBALS['T3_VAR']['t3editorObj']->getCodeEditor(
-                                               'data[constants]',
-                                               'fixed-font enable-tab',
-                                               t3lib_div::formatForTextarea($parameters['tplRow']['constants']),
-                                               $attributes,
-                                               $title,
-                                               array(
-                                                       'pageId' => intval($pObj->pObj->id),
-                                                       't3editor_savetype' => 'tx_tstemplateinfo',
-                                               )
-                                       );
-                       $parameters['theOutput'] = preg_replace(
-                               '/\<textarea name="data\[constants\]".*\>([^\<]*)\<\/textarea\>/mi',
-                               $outCode,
-                               $parameters['theOutput']
-                               );
-               }
-
-               // Template Setup
-               if ($parameters['e']['config']) {
-                       $attributes = 'rows="' . $parameters['numberOfRows'] . '" ' .
-                               'wrap="off" ' .
-                               $pObj->pObj->doc->formWidthText(48, 'width:98%;height:60%', 'off');
-
-                       $title = $GLOBALS['LANG']->getLL('template') . ' ' .
-                               htmlspecialchars($parameters['tplRow']['title']) .
-                               $GLOBALS['LANG']->getLL('delimiter') . ' ' .
-                               $GLOBALS['LANG']->getLL('setup');
-
-                       $outCode = $GLOBALS['T3_VAR']['t3editorObj']->getCodeEditor(
-                                               'data[config]',
-                                               'fixed-font enable-tab',
-                                               t3lib_div::formatForTextarea($parameters['tplRow']['config']),
-                                               $attributes,
-                                               $title,
-                                               array(
-                                                       'pageId' => intval($pObj->pObj->id),
-                                                       't3editor_savetype' => 'tx_tstemplateinfo',
-                                               )
-                                       );
-                       $parameters['theOutput'] = preg_replace(
-                               '/\<textarea name="data\[config\]".*\>([^\<]*)\<\/textarea\>/mi',
-                               $outCode,
-                               $parameters['theOutput']
-                               );
-               }
-       }
-
-       /**
-        * Save the content from t3editor retrieved via Ajax
-        *
-        * new Ajax.Request('/dev/t3e/dummy/typo3/ajax.php', {
-        *      parameters: {
-        *              ajaxID: 'tx_t3editor::saveCode',
-        *              t3editor_savetype: 'tx_tstemplateinfo'
-        *      }
-        * });
-        *
-        * @param array params  Parameters (not used yet)
-        * @param TYPO3AJAX ajaxObj     AjaxObject to handle response
-        */
-       public function saveCode($params, $ajaxObj) {
-               // cancel if its not an Ajax request
-               if((TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_AJAX)) {
-                       $ajaxObj->setContentFormat('json');
-                       $codeType = t3lib_div::_GP('t3editor_savetype');
-                       $savingsuccess = false;
-
-                       switch ($codeType) {
-                               case 'tx_tstemplateinfo':
-                                       $savingsuccess = $this->saveCodeTsTemplateInfo();
-                                       break;
-
-                               // TODO: fileadmin, extmng, TCEform, ...
-
-                               default:
-                                       $ajaxObj->setError($GLOBALS['LANG']->getLL('unknownContentType') . ' ' . $codeType);
-                       }
-                       $ajaxObj->setContent(array('result' => $savingsuccess));
-               }
-       }
-
-       /**
-        * Process saving request like in class.tstemplateinfo.php (TCE processing)
-        *
-        * @return boolean true if successful
-        */
-       public function saveCodeTsTemplateInfo() {
-               $savingsuccess = false;
-
-               $pageId = t3lib_div::_GP('pageId');
-
-               if (!is_numeric($pageId) || $pageId < 1) {
-                       return false;
-               }
-
-               // if given use the requested template_uid
-               // if not, use the first template-record on the page (in this case there should only be one record!)
-               $set = t3lib_div::_GP('SET');
-               $template_uid = $set['templatesOnPage'] ? $set['templatesOnPage'] : 0;
-
-               $tmpl = t3lib_div::makeInstance('t3lib_tsparser_ext');  // Defined global here!
-               $tmpl->tt_track = 0;    // Do not log time-performance information
-               $tmpl->init();
-
-               // Get the row of the first VISIBLE template of the page. whereclause like the frontend.
-               $tplRow = $tmpl->ext_getFirstTemplate($pageId, $template_uid);
-               $existTemplate = (is_array($tplRow) ? true : false);
-
-               if ($existTemplate)     {
-                       $saveId = ($tplRow['_ORIG_uid'] ? $tplRow['_ORIG_uid'] : $tplRow['uid']);
-
-                       // Update template ?
-                       $POST = t3lib_div::_POST();
-
-                       if ($POST['submit']) {
-                               require_once(PATH_t3lib . 'class.t3lib_tcemain.php');
-
-                               // Set the data to be saved
-                               $recData = array();
-
-                               if (is_array($POST['data'])) {
-                                       foreach ($POST['data'] as $field => $val) {
-                                               switch ($field) {
-                                                       case 'constants':
-                                                       case 'config':
-                                                       case 'title':
-                                                       case 'sitetitle':
-                                                       case 'description':
-                                                               $recData['sys_template'][$saveId][$field] = $val;
-                                                               break;
-                                               }
-                                       }
-                               }
-                               if (count($recData)) {
-                                       // Create new tce-object
-                                       $tce = t3lib_div::makeInstance('t3lib_TCEmain');
-                                       $tce->stripslashes_values = 0;
-
-                                       // Initialize
-                                       $tce->start($recData, array());
-
-                                       // Saved the stuff
-                                       $tce->process_datamap();
-
-                                       // Clear the cache (note: currently only admin-users can clear the
-                                       // cache in tce_main.php)
-                                       $tce->clear_cacheCmd('all');
-
-                                       $savingsuccess = true;
-                               }
-                       }
-               }
-               return $savingsuccess;
-       }
-
-       /**
-        * Gets plugins that are defined at $TYPO3_CONF_VARS['EXTCONF']['t3editor']['plugins']
-        * (called by typo3/ajax.php)
-        *
-        * @param       array           $params: additional parameters (not used here)
-        * @param       TYPO3AJAX       &$ajaxObj: the TYPO3AJAX object of this request
-        * @return      void
-        * @author      Oliver Hader <oliver@typo3.org>
-        */
-       public function getPlugins($params, TYPO3AJAX &$ajaxObj) {
-               $result = array();
-               $plugins =& $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['t3editor']['plugins'];
-
-               if (is_array($plugins)) {
-                       $result = array_values($plugins);
-               }
-
-               $ajaxObj->setContent($result);
-               $ajaxObj->setContentFormat('jsonbody');
-       }
-}
-
-
-
-if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/t3editor/class.tx_t3editor.php']) {
-       include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/t3editor/class.tx_t3editor.php']);
-}
-
-?>
\ No newline at end of file
diff --git a/typo3/sysext/t3editor/classes/class.tx_t3editor.php b/typo3/sysext/t3editor/classes/class.tx_t3editor.php
new file mode 100644 (file)
index 0000000..1c05d3b
--- /dev/null
@@ -0,0 +1,401 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2007-2010 Tobias Liebig <mail_typo3@etobi.de>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+
+/**
+ * Provides a javascript-driven code editor with syntax highlighting for TS, HTML, CSS and more
+ *
+ * @author     Tobias Liebig <mail_typo3@etobi.de>
+ */
+
+$GLOBALS['LANG']->includeLLFile('EXT:t3editor/locallang.xml');
+
+class tx_t3editor implements t3lib_Singleton {
+
+       const MODE_TYPOSCRIPT = 'typoscript';
+       const MODE_JAVASCRIPT = 'javascript';
+       const MODE_CSS = 'css';
+       const MODE_XML = 'xml';
+
+       protected $mode = '';
+       
+       /**
+        * counts the editors on the current page
+        *
+        * @var         int
+        */
+       protected $editorCounter = 0;
+
+       /**
+        * flag to enable the t3editor
+        *
+        * @var         bool
+        */
+       protected $_isEnabled = true;
+
+       /**
+        * sets the type of code to edit (::MODE_TYPOSCRIPT, ::MODE_JAVASCRIPT)
+        *
+        * @param       $mode   string expects one of the predefined constants
+        * @return      tx_t3editor
+        */
+       public function setMode($mode) {
+               $this->mode = $mode;
+               return $this;
+       }
+
+       /**
+        * @return      boolean         true if the t3editor is enabled
+        */
+       public function isEnabled() {
+               return $this->_isEnabled;
+       }
+
+       /**
+        * Creates a new instance of the class
+        *
+        * @return      void
+        */
+       public function __construct() {
+               $this->checkEditorIsDisabled();
+
+                       // disable pmktextarea to avoid conflicts (thanks Peter Klein for this suggestion)
+               $GLOBALS["BE_USER"]->uc['disablePMKTextarea'] = 1;
+       }
+
+       /**
+        * check if the t3editor should be disabled (by a POST value)
+        */
+       protected function checkEditorIsDisabled() {
+               $editorIsDisabled = t3lib_div::_POST('t3editor_disableEditor');
+
+               if (!empty($editorIsDisabled)) {
+                       $editorIsDisabled = ($editorIsDisabled == 'true');
+               } else {
+                       $editorIsDisabled = $GLOBALS['BE_USER']->uc['disableT3Editor'];
+               }
+
+               if ($GLOBALS['BE_USER']->uc['disableT3Editor'] != $editorIsDisabled) {
+                       $GLOBALS['BE_USER']->uc['disableT3Editor'] = $editorIsDisabled;
+                       $GLOBALS['BE_USER']->writeUC();
+               }
+       }
+
+       /**
+        * Retrieves JavaScript code (header part) for editor
+        *
+        * @param       template        $doc
+        * @return      string          JavaScript code
+        */
+       public function getJavascriptCode($doc) {
+               $content = '';
+
+               if ($this->isEnabled()) {
+
+                       $path_t3e = t3lib_extmgm::extRelPath('t3editor');
+
+                               // include needed javascript-frameworks
+                       /** @var $pageRenderer t3lib_PageRenderer */
+                       $pageRenderer = $doc->getPageRenderer();
+                       $pageRenderer->loadPrototype();
+                       $pageRenderer->loadScriptaculous();
+
+                               // include editor-css
+                       $content .= '<link href="' .
+                               $GLOBALS['BACK_PATH'] .
+                               t3lib_extmgm::extRelPath('t3editor') .
+                               'res/css/t3editor.css' .
+                               '" type="text/css" rel="stylesheet" />';
+
+                               // include editor-js-lib
+                       $doc->loadJavascriptLib($path_t3e . 'res/jslib/codemirror/codemirror.js');
+                       $doc->loadJavascriptLib($path_t3e . 'res/jslib/t3editor.js');
+
+                       if ($this->mode == self::MODE_TYPOSCRIPT) {
+                               $doc->loadJavascriptLib($path_t3e . 'res/jslib/ts_codecompletion/tsref.js');
+                               $doc->loadJavascriptLib($path_t3e . 'res/jslib/ts_codecompletion/completionresult.js');
+                               $doc->loadJavascriptLib($path_t3e . 'res/jslib/ts_codecompletion/tsparser.js');
+                               $doc->loadJavascriptLib($path_t3e . 'res/jslib/ts_codecompletion/tscodecompletion.js');
+                       }
+
+                       $content .= t3lib_div::wrapJS(
+                               'T3editor = T3editor || {};' .
+                               'T3editor.lang = ' . json_encode($this->getJavaScriptLabels()) .';' . chr(10).
+                               'T3editor.PATH_t3e = "' . $GLOBALS['BACK_PATH'] . t3lib_extmgm::extRelPath('t3editor') . '"; ' . chr(10).
+                               'T3editor.URL_typo3 = "' . htmlspecialchars(t3lib_div::getIndpEnv('TYPO3_SITE_URL') . TYPO3_mainDir) . '"; ' .chr(10).
+                               'T3editor.template = '. $this->getPreparedTemplate() .';' .chr(10).
+                               'T3editor.parserfile = ' . $this->getParserfileByMode($this->mode) . ';' .chr(10). 
+                               'T3editor.stylesheet = ' . $this->getStylesheetByMode($this->mode) . ';'
+                       );
+               }
+
+               return $content;
+       }
+
+       /**
+        * get the template code, prepared for javascript (no line breaks, quoted in slinge quotes)
+        *
+        * @return      string  the template code, prepared to use in javascript
+        */
+       protected function getPreparedTemplate() {
+               $T3Editor_template = t3lib_div::getURL(
+                       t3lib_div::getFileAbsFileName(
+                               'EXT:t3editor/res/templates/t3editor.html'
+                       )
+               );
+               $T3Editor_template = addslashes($T3Editor_template);
+               $T3Editor_template = str_replace("\n", "' + '", $T3Editor_template);
+
+               return '\'' . $T3Editor_template . '\'';
+       }
+
+       /**
+        * determine the correct parser js file for given mode
+        *
+        * @param       string  $mode
+        * @return      string  parser file name
+        */
+       protected function getParserfileByMode($mode) {
+               switch ($mode) {
+                       case tx_t3editor::MODE_TYPOSCRIPT:
+                               $parserfile = '["tokenizetyposcript.js", "parsetyposcript.js"]';
+                       break;
+
+                       case tx_t3editor::MODE_JAVASCRIPT:
+                               $parserfile = '["tokenizejavascript.js", "parsejavascript.js"]';
+                       break;
+
+                       case tx_t3editor::MODE_CSS:
+                               $parserfile = '"parsecss.js"';
+                       break;
+
+                       case tx_t3editor::MODE_XML:
+                               $parserfile = '"parsexml.js"';
+                       break;
+               }
+               return $parserfile;
+       }
+
+       /**
+        * determine the correct css file for given mode
+        *
+        * @param       string  $mode
+        * @return      string  css file name
+        */
+       protected function getStylesheetByMode($mode) {
+               switch ($mode) {
+                       case tx_t3editor::MODE_TYPOSCRIPT:
+                               $stylesheet = '"res/css/typoscriptcolors.css"';
+                       break;
+
+                       case tx_t3editor::MODE_JAVASCRIPT:
+                               $stylesheet = '"res/css/jscolors.css"';
+                       break;
+
+                       case tx_t3editor::MODE_CSS:
+                               $stylesheet = '"res/css/csscolors.css"';
+                       break;
+
+                       case tx_t3editor::MODE_XML:
+                               $stylesheet = '"res/css/xmlcolors.css"';
+                       break;
+               }
+               return '[T3editor.PATH_t3e + "res/css/t3editor_inner.css", T3editor.PATH_t3e + ' . $stylesheet . ']';
+       }
+
+       /**
+        * Gets the labels to be used in JavaScript in the Ext JS interface.
+        * TODO this method is copied from EXT:Recycler, maybe this should be refactored into a helper class
+        *
+        * @return      array           The labels to be used in JavaScript
+        */
+       protected function getJavaScriptLabels() {
+               $coreLabels = array();
+               $extensionLabels = $this->getJavaScriptLabelsFromLocallang('js.', 'label_');
+               return array_merge($coreLabels, $extensionLabels);
+       }
+
+       /**
+        * Gets labels to be used in JavaScript fetched from the current locallang file.
+        * TODO this method is copied from EXT:Recycler, maybe this should be refactored into a helper class
+        *
+        * @param       string          $selectionPrefix: Prefix to select the correct labels (default: 'js.')
+        * @param       string          $stripFromSelectionName: Sub-prefix to be removed from label names in the result (default: '')
+        * @return      array           Lables to be used in JavaScript of the current locallang file
+        * @todo        Check, whether this method can be moved in a generic way to $GLOBALS['LANG']
+        */
+       protected function getJavaScriptLabelsFromLocallang($selectionPrefix = 'js.', $stripFromSelectionName = '') {
+               $extraction = array();
+               $labels = array_merge(
+                       (array)$GLOBALS['LOCAL_LANG']['default'],
+                       (array)$GLOBALS['LOCAL_LANG'][$GLOBALS['LANG']->lang]
+               );
+                       // Regular expression to strip the selection prefix and possibly something from the label name:
+               $labelPattern = '#^' . preg_quote($selectionPrefix, '#') . '(' . preg_quote($stripFromSelectionName, '#') . ')?#';
+                       // Iterate throuh all locallang lables:
+               foreach ($labels as $label => $value) {
+                       if (strpos($label, $selectionPrefix) === 0) {
+                               $key = preg_replace($labelPattern, '', $label);
+                               $extraction[$key] = $value;
+                       }
+               }
+               return $extraction;
+       }
+
+       /**
+        * Generates HTML with code editor
+        *
+        * @param       string          $name   Name attribute of HTML tag
+        * @param       string          $class  Class attribute of HTML tag
+        * @param       string          $content        Content of the editor
+        * @param       string          $additionalParams       Any additional editor parameters
+        * @param       string          $alt    Alt attribute
+        * @return      string          Generated HTML code for editor
+        */
+       public function getCodeEditor($name, $class='', $content='', $additionalParams='', $alt='', array $hiddenfields = array()) {
+               $code = '';
+
+               if ($this->isEnabled()) {
+                       $this->editorCounter++;
+
+                       $class .= ' t3editor';
+                       if (!empty($alt)) {
+                               $alt = ' alt="' . $alt . '"';
+                       }
+
+                       $code .= '<div>' .
+                               '<textarea id="t3editor_' . $this->editorCounter . '" ' .
+                               'name="' . $name . '" ' .
+                               'class="' . $class . '" ' .
+                               $additionalParams . ' ' .
+                               $alt . '>' .
+                               $content .
+                               '</textarea></div>';
+
+                       $checked = $GLOBALS['BE_USER']->uc['disableT3Editor'] ? 'checked="checked"' : '';
+
+                       $code .= '<br /><br />' .
+                               '<input type="checkbox" ' .
+                               'class="checkbox t3editor_disableEditor" ' .
+                               'onclick="T3editor.toggleEditor(this);" ' .
+                               'name="t3editor_disableEditor" ' .
+                               'value="true" ' .
+                               'id="t3editor_disableEditor_' . $this->editorCounter . '_checkbox" ' .
+                               $checked.' />&nbsp;' .
+                               '<label for="t3editor_disableEditor_' . $this->editorCounter . '_checkbox">' .
+                               $GLOBALS['LANG']->getLL('deactivate') .
+                               '</label>' .
+                               '<br /><br />';
+
+                       if (count($hiddenfields)) {
+                               foreach ($hiddenfields as $name => $value) {
+                                       $code.= '<input type="hidden" ' .
+                                               'name="' . $name . '" ' .
+                                               'value="' . $value .
+                                               '" />';
+                               }
+                       }
+
+               } else {
+                       // fallback
+                       if (!empty($class)) {
+                               $class = 'class="' . $class . '" ';
+                       }
+
+                       $code .= '<textarea name="' . $name . '" ' .
+                               $class . $additionalParams.'>' .
+                               $content . '</textarea>';
+               }
+
+               return $code;
+       }
+
+
+
+       /**
+        * Save the content from t3editor retrieved via Ajax
+        *
+        * new Ajax.Request('/dev/t3e/dummy/typo3/ajax.php', {
+        *      parameters: {
+        *              ajaxID: 'tx_t3editor::saveCode',
+        *              t3editor_savetype: 'tx_tstemplateinfo'
+        *      }
+        * });
+        *
+        * @param array params  Parameters (not used yet)
+        * @param TYPO3AJAX ajaxObj     AjaxObject to handle response
+        */
+       public function ajaxSaveCode($params, $ajaxObj) {
+               // cancel if its not an Ajax request
+               if((TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_AJAX)) {
+                       $ajaxObj->setContentFormat('json');
+                       $codeType = t3lib_div::_GP('t3editor_savetype');
+                       $savingsuccess = false;
+
+                       if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/t3editor/classes/class.tx_t3editor.php']['ajaxSaveCode'])) {
+                               $_params = array(
+                                       'pObj' => &$this,
+                                       'type' => $codeType
+                               );
+                               foreach($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/t3editor/classes/class.tx_t3editor.php']['ajaxSaveCode'] as $key => $_funcRef)   {
+                                       $savingsuccess = t3lib_div::callUserFunction($_funcRef,$_params,$this) || $savingsuccess;
+                               }
+                       }
+
+                       $ajaxObj->setContent(array('result' => $savingsuccess));
+               }
+       }
+
+       /**
+        * Gets plugins that are defined at $TYPO3_CONF_VARS['EXTCONF']['t3editor']['plugins']
+        * (called by typo3/ajax.php)
+        *
+        * @param       array           $params: additional parameters (not used here)
+        * @param       TYPO3AJAX       &$ajaxObj: the TYPO3AJAX object of this request
+        * @return      void
+        * @author      Oliver Hader <oliver@typo3.org>
+        */
+       public function getPlugins($params, TYPO3AJAX &$ajaxObj) {
+               $result = array();
+               $plugins =& $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['t3editor']['plugins'];
+
+               if (is_array($plugins)) {
+                       $result = array_values($plugins);
+               }
+
+               $ajaxObj->setContent($result);
+               $ajaxObj->setContentFormat('jsonbody');
+       }
+}
+
+
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/t3editor/classes/class.tx_t3editor.php']) {
+       include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/t3editor/classes/class.tx_t3editor.php']);
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/t3editor/classes/class.tx_t3editor_hooks_tstemplateinfo.php b/typo3/sysext/t3editor/classes/class.tx_t3editor_hooks_tstemplateinfo.php
new file mode 100644 (file)
index 0000000..7747870
--- /dev/null
@@ -0,0 +1,196 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2007-2010 Tobias Liebig <mail_typo3@etobi.de>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+require_once(t3lib_extMgm::extPath('t3editor', 'classes/class.tx_t3editor.php'));
+
+class tx_t3editor_hooks_tstemplateinfo {
+
+       /**
+        *
+        * @var tx_t3editor
+        */
+       protected $t3editor = NULL;
+
+       /**
+        *
+        * @return tx_t3editor
+        */
+       protected function getT3editor() {
+               if ($this->t3editor == NULL) {
+                       $this->t3editor = t3lib_div::makeInstance('tx_t3editor')
+                               ->setMode(tx_t3editor::MODE_TYPOSCRIPT);
+               }
+               return $this->t3editor;
+       }
+
+       /**
+        * Hook-function: inject t3editor JavaScript code before the page is compiled
+        * called in typo3/template.php:startPage
+        *
+        * @param array $parameters
+        * @param template $pObj
+        */
+       public function preStartPageHook($parameters, $pObj) {
+               // enable editor in Template-Modul
+               if (preg_match('/sysext\/tstemplate\/ts\/index\.php/', $_SERVER['SCRIPT_NAME'])) {
+
+                       $t3editor = $this->getT3editor();
+
+                       // insert javascript code in document header
+                       $pObj->JScode .= $t3editor->getJavascriptCode($pObj);
+                       $pObj->loadJavascriptLib(t3lib_extmgm::extRelPath('t3editor') . 'res/jslib/tx_tstemplateinfo/tx_tstemplateinfo.js');
+               }
+       }
+
+
+       /**
+        * Hook-function:
+        * called in typo3/sysext/tstemplate_info/class.tx_tstemplateinfo.php
+        *
+        * @param array $parameters
+        * @param tx_tstemplateinfo $pObj
+        */
+       public function postOutputProcessingHook($parameters, $pObj) {
+               $t3editor = $this->getT3editor();
+
+               if (!$t3editor->isEnabled()) {
+                       return;
+               }
+
+               foreach (array('constants', 'config') as $type) {
+                       if ($parameters['e'][$type]) {
+                               $attributes = 'rows="' . $parameters['numberOfRows'] . '" ' .
+                                       'wrap="off" ' .
+                                       $pObj->pObj->doc->formWidthText(48, 'width:98%;height:60%', 'off');
+
+                               $title = $GLOBALS['LANG']->getLL('template') . ' ' .
+                                       htmlspecialchars($parameters['tplRow']['title']) .
+                                       $GLOBALS['LANG']->getLL('delimiter') . ' ' .
+                                       $GLOBALS['LANG']->getLL($type);
+
+                               $outCode = $t3editor->getCodeEditor(
+                                       'data[' . $type . ']',
+                                       'fixed-font enable-tab',
+                                       t3lib_div::formatForTextarea($parameters['tplRow'][$type]),
+                                       $attributes,
+                                       $title,
+                                       array(
+                                               'pageId' => intval($pObj->pObj->id)
+                                       )
+                               );
+                               $parameters['theOutput'] = preg_replace(
+                                       '/\<textarea name="data\[' . $type . '\]".*\>([^\<]*)\<\/textarea\>/mi',
+                                       $outCode,
+                                       $parameters['theOutput']
+                               );
+                       }
+               }
+       }
+
+
+       /**
+        * Process saving request like in class.tstemplateinfo.php (TCE processing)
+        *
+        * @return boolean true if successful
+        */
+       public function save($parameters, $pObj) {
+               $savingsuccess = false;
+               if ($parameters['type'] == 'tx_tstemplateinfo') {
+
+                       $pageId = t3lib_div::_GP('pageId');
+                       if (!is_numeric($pageId) || $pageId < 1) {
+                               return false;
+                       }
+
+                       // if given use the requested template_uid
+                       // if not, use the first template-record on the page (in this case there should only be one record!)
+                       $set = t3lib_div::_GP('SET');
+                       $template_uid = $set['templatesOnPage'] ? $set['templatesOnPage'] : 0;
+
+                       $tmpl = t3lib_div::makeInstance('t3lib_tsparser_ext');  // Defined global here!
+                       $tmpl->tt_track = 0;    // Do not log time-performance information
+                       $tmpl->init();
+
+                       // Get the row of the first VISIBLE template of the page. whereclause like the frontend.
+                       $tplRow = $tmpl->ext_getFirstTemplate($pageId, $template_uid);
+                       $existTemplate = (is_array($tplRow) ? true : false);
+
+                       if ($existTemplate)     {
+                               $saveId = ($tplRow['_ORIG_uid'] ? $tplRow['_ORIG_uid'] : $tplRow['uid']);
+
+                               // Update template ?
+                               $POST = t3lib_div::_POST();
+
+                               if ($POST['submit']) {
+                                       require_once(PATH_t3lib . 'class.t3lib_tcemain.php');
+
+                                       // Set the data to be saved
+                                       $recData = array();
+
+                                       if (is_array($POST['data'])) {
+                                               foreach ($POST['data'] as $field => $val) {
+                                                       switch ($field) {
+                                                               case 'constants':
+                                                               case 'config':
+                                                               case 'title':
+                                                               case 'sitetitle':
+                                                               case 'description':
+                                                                       $recData['sys_template'][$saveId][$field] = $val;
+                                                                       break;
+                                                       }
+                                               }
+                                       }
+                                       if (count($recData)) {
+                                               // Create new tce-object
+                                               $tce = t3lib_div::makeInstance('t3lib_TCEmain');
+                                               $tce->stripslashes_values = 0;
+
+                                               // Initialize
+                                               $tce->start($recData, array());
+
+                                               // Saved the stuff
+                                               $tce->process_datamap();
+
+                                               // Clear the cache (note: currently only admin-users can clear the
+                                               // cache in tce_main.php)
+                                               $tce->clear_cacheCmd('all');
+
+                                               $savingsuccess = true;
+                                       }
+                               }
+                       }
+               }
+               return $savingsuccess;
+       }
+}
+
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/t3editor/classes/class.tx_t3editor_hooks_tstemplateinfo.php']) {
+       include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/t3editor/classes/class.tx_t3editor_hooks_tstemplateinfo.php']);
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/t3editor/classes/ts_codecompletion/class.tx_t3editor_codecompletion.php b/typo3/sysext/t3editor/classes/ts_codecompletion/class.tx_t3editor_codecompletion.php
new file mode 100644 (file)
index 0000000..4ead8f7
--- /dev/null
@@ -0,0 +1,173 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2008-2009 Stephan Petzl <spetzl@gmx.at> and Christian Kartnig <office@hahnepeter.de>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+require_once(PATH_t3lib.'class.t3lib_page.php');
+$GLOBALS['LANG']->includeLLFile('EXT:t3editor/locallang.xml');
+
+class tx_t3editor_codecompletion {
+       /** @var TYPO3AJAX */
+       protected $ajaxObj;
+
+       /**
+        * General processor for AJAX requests.
+        * (called by typo3/ajax.php)
+        *
+        * @param       array           $params: additional parameters (not used here)
+        * @param       TYPO3AJAX       &$ajaxObj: the TYPO3AJAX object of this request
+        * @return      void
+        * @author      Oliver Hader <oliver@typo3.org>
+        */
+       public function processAjaxRequest($params, TYPO3AJAX &$ajaxObj) {
+               $this->ajaxObj = $ajaxObj;
+
+               $ajaxIdParts = explode('::', $ajaxObj->getAjaxID(), 2);
+               $ajaxMethod = $ajaxIdParts[1];
+               $response = array();
+
+               // Process the AJAX requests:
+               if ($ajaxMethod == 'loadTemplates') {
+                       $ajaxObj->setContent($this->loadTemplates(
+                               intval(t3lib_div::_GP('pageId')))
+                       );
+                       $ajaxObj->setContentFormat('jsonbody');
+               }
+       }
+
+       /**
+        * Loads all templates up to a given page id (walking the rootline) and
+        * cleans parts that are not required for the t3editor codecompletion.
+        *
+        * @param       integer         $pageId: id of the page
+        * @param       integer         $templateId: currently unused (default: 0)
+        * @return      array           Cleaned array of TypoScript information
+        * @author      Oliver Hader <oliver@typo3.org>
+        */
+       protected function loadTemplates($pageId, $templateId = 0) {
+               $templates = array();
+
+                       // Check whether access is granted (only admin have access to sys_template records):
+               if ($GLOBALS['BE_USER']->isAdmin()) {
+                               // Check whether there is a pageId given:
+                       if ($pageId) {
+                               $templates = $this->getMergedTemplates($pageId);
+                               // Otherwise, set an error:
+                       } else {
+                               $this->ajaxObj->setError($GLOBALS['LANG']->getLL('pageIDInteger'));
+                       }
+                       // Set an error if user has no access to sys_template records:
+               } else {
+                       $this->ajaxObj->setError($GLOBALS['LANG']->getLL('noPermission'));
+               }
+
+               return $templates;
+       }
+
+       /**
+        * Gets merged templates by walking the rootline to a given page id.
+        *
+        * @todo        oliver@typo3.org: Refactor this method and comment what's going on there
+        * @param       integer         $pageId
+        * @param       integer         $templateId
+        * @return      array           Setup part of merged template records
+        */
+       protected function getMergedTemplates($pageId, $templateId = 0) {
+               $result = array();
+
+               /** @var $tsParser t3lib_tsparser_ext */
+               $tsParser = t3lib_div::makeInstance('t3lib_tsparser_ext');
+               $tsParser->tt_track = 0;
+               $tsParser->init();
+                       // Gets the rootLine
+               $page = t3lib_div::makeInstance('t3lib_pageSelect');
+               $rootLine = $page->getRootLine($pageId);
+
+                       // This generates the constants/config + hierarchy info for the template.
+               $tsParser->runThroughTemplates($rootLine);
+
+               // ts-setup & ts-constants of the currently edited template should not be included
+               // therefor we have to delete the last template from the stack
+               array_pop($tsParser->config);
+               array_pop($tsParser->constants);
+
+               // some of the lines are not clear to me... do we need them?
+               //$tsParser->matchAlternative[] = 'dummydummydummydummydummydummydummydummydummydummydummy';            // This is just here to make sure that at least one element is in the array so that the tsparser actually uses this array to match.
+               //$tsParser->regexMode = $this->pObj->MOD_SETTINGS["ts_browser_regexsearch"];
+               // ??
+               //$tsParser->fixedLgd=$this->pObj->MOD_SETTINGS["ts_browser_fixedLgd"];
+               //$tsParser->matchAlternative = $this->pObj->MOD_SETTINGS['tsbrowser_conditions'];
+               $tsParser->linkObjects = TRUE;
+               $tsParser->ext_regLinenumbers = FALSE;
+               $tsParser->bType=$bType;
+               $tsParser->resourceCheck=1;
+               $tsParser->uplPath = PATH_site . $tsParser->uplPath;
+               $tsParser->removeFromGetFilePath = PATH_site;
+               $tsParser->generateConfig();
+
+               $result = $this->treeWalkCleanup($tsParser->setup);
+
+               return $result;
+       }
+
+       /**
+        * Walks through a tree of TypoScript configuration an cleans it up.
+        *
+        * @TODO        oliver@typo3.org: Define and comment why this is necessary and exactly happens below
+        * @param       array           $treeBranch: TypoScript configuration or sub branch of it
+        * @return      array           Cleaned TypoScript branch
+        */
+       private function treeWalkCleanup(array $treeBranch){
+               $cleanedTreeBranch = array();
+
+               foreach ($treeBranch as $key => $value) {
+                       $dotCount = substr_count($key, '.');
+                       if ($dotCount == 0){    //type definition or value-assignment
+                               if ($value != '') {
+                                       if (strlen($value) > 20) {
+                                               $value = substr($value, 0, 20);
+                                       }
+                                       if (!isset($cleanedTreeBranch[$key])) {
+                                               $cleanedTreeBranch[$key] = array();
+                                       }
+                                       $cleanedTreeBranch[$key]['v'] = $value;
+                               }
+                       } else if ($dotCount == 1) { // subtree (definition of properties)
+                               $subBranch = $this->treeWalkCleanup($value);
+                               if ($subBranch) {
+                                       $key = str_replace('.', '', $key);
+                                       if (!isset($cleanedTreeBranch[$key])) {
+                                               $cleanedTreeBranch[$key] = array();
+                                       }
+                                       $cleanedTreeBranch[$key]['c'] = $subBranch;
+                               }
+                       } //in other cases do nothing (this information (lineNo,..) is not needed in the editor)
+               }
+
+               return $cleanedTreeBranch;
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/t3editor/classes/ts_codecompletion/class.tx_t3editor_tsrefloader.php b/typo3/sysext/t3editor/classes/ts_codecompletion/class.tx_t3editor_tsrefloader.php
new file mode 100644 (file)
index 0000000..7dcc15e
--- /dev/null
@@ -0,0 +1,185 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2008-2009 Stephan Petzl <spetzl@gmx.at> and Christian Kartnig <office@hahnepeter.de>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Loads TSref information from a XML file an responds to an AJAX call.
+ *
+ * @TODO Refactor and correct phpDoc comments
+ * @package TYPO3
+ * @author Stephan Petzl <spetzl@gmx.at>
+ * @author Christian Kartnig <office@hahnepeter.de>
+ */
+
+$GLOBALS['LANG']->includeLLFile('EXT:t3editor/locallang.xml');
+
+class tx_t3editor_TSrefLoader {
+       /** @var DOMDocument */
+       protected $xmlDoc;
+
+       /** @var TYPO3AJAX */
+       protected $ajaxObj;
+
+       /**
+        * General processor for AJAX requests.
+        * (called by typo3/ajax.php)
+        *
+        * @param       array           $params: additional parameters (not used here)
+        * @param       TYPO3AJAX       &$ajaxObj: the TYPO3AJAX object of this request
+        * @return      void
+        * @author      Oliver Hader <oliver@typo3.org>
+        */
+       public function processAjaxRequest($params, TYPO3AJAX &$ajaxObj) {
+               $this->ajaxObj = $ajaxObj;
+
+               // Load the TSref XML information:
+               $this->loadFile(t3lib_extMgm::extPath('t3editor') . 'res/tsref/tsref.xml');
+
+               $ajaxIdParts = explode('::', $ajaxObj->getAjaxID(), 2);
+               $ajaxMethod = $ajaxIdParts[1];
+               $response = array();
+
+               // Process the AJAX requests:
+               if ($ajaxMethod == 'getTypes') {
+                       $ajaxObj->setContent($this->getTypes());
+                       $ajaxObj->setContentFormat('jsonbody');
+               } elseif ($ajaxMethod == 'getDescription') {
+                       $ajaxObj->addContent(
+                               '',
+                               $this->getDescription(
+                                       t3lib_div::_GP('typeId'),
+                                       t3lib_div::_GP('parameterName')
+                               )
+                       );
+                       $ajaxObj->setContentFormat('plain');
+               }
+       }
+
+       /**
+        * Enter description here...
+        *
+        * @param       string          $filepath
+        * @return      void
+        */
+       protected function loadFile($filepath) {
+               $this->xmlDoc = new DOMDocument('1.0', 'utf-8');
+               $this->xmlDoc->load($filepath);
+
+               // @TODO: oliver@typo3.org: I guess this is not required here
+               $this->xmlDoc->saveXML();
+       }
+
+       /**
+        * Enter description here...
+        *
+        * @return      array
+        */
+       protected function getTypes() {
+               $types = $this->xmlDoc->getElementsByTagName('type');
+               $typeArr = array();
+               foreach($types as $type){
+                       $typeId = $type->getAttribute('id');
+                       $typeName = $type->getAttribute('name');
+                       if(!$typeName) {
+                               $typeName = $typeId;
+                       }
+                       $properties = $type->getElementsByTagName('property');
+                       $propArr = array();
+                       foreach($properties as $property) {
+                               $p = array();
+                               $p['name'] = $property->getAttribute('name');
+                               $p['type'] = $property->getAttribute('type');
+                               $propArr[$property->getAttribute('name')] = $p;
+                       }
+                       $typeArr[$typeId] = array();
+                       $typeArr[$typeId]['properties'] = $propArr;
+                       $typeArr[$typeId]['name'] = $typeName;
+                       if($type->hasAttribute('extends')) {
+                               $typeArr[$typeId]['extends'] = $type->getAttribute('extends');
+                       }
+               }
+               return $typeArr;
+       }
+
+       /**
+        * Enter description here...
+        *
+        * @param       string          $typeId
+        * @param       string          $parameterName
+        * @return      string
+        */
+       protected function getDescription($typeId, $parameterName = '') {
+               if (!$typeId) {
+                       $this->ajaxObj->setError($GLOBALS['LANG']->getLL('typeIDMissing'));
+                       return '';
+               }
+
+               // getElementById does only work with schema
+               $type = $this->getType($typeId);
+               if ($parameterName) {  //retrieve propertyDescription
+                       $properties = $type->getElementsByTagName('property');
+                       foreach ($properties as $propery) {
+                               $propName = $propery->getAttribute('name');
+                               if ($propName == $parameterName) {
+                                       $descriptions = $propery->getElementsByTagName('description');
+                                       if ($descriptions->length) {
+                                               $description = $descriptions->item(0)->textContent;
+                                               $description = htmlspecialchars($description);
+                                               $description = nl2br($description);
+                                               return $description;
+                                       }
+                               }
+                       }
+               } else {  // retrieve typedescription
+                       /*
+                       $descriptions = $type->getElementsByTagName('description');
+                       if($descriptions->length){
+                               $description = $descriptions->item(0)->textContent;
+
+                               return htmlspecialchars($description);
+                       }*/
+               }
+
+               return '';
+       }
+
+       /**
+        * Enter description here...
+        *
+        * @param       string          $typeId
+        * @return      DOMNode
+        */
+       protected function getType($typeId) {
+               $types = $this->xmlDoc->getElementsByTagName('type');
+               foreach ($types as $type) {
+                       if ($type->getAttribute('id') == $typeId) {
+                               return $type;
+                       }
+               }
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/t3editor/css/t3editor.css b/typo3/sysext/t3editor/css/t3editor.css
deleted file mode 100755 (executable)
index 0f4bb07..0000000
+++ /dev/null
@@ -1,239 +0,0 @@
-.TSREF_type_label, .TSREF_description_label{
-       font-weight: bold;
-}
-.t3e_codeCompleteBox ul li span.word_definedTSREFProperty {
-       color:#DF4E00;
-       font-size:0.95em;
-       font-weight:bold;
-}
-.t3e_codeCompleteBox ul li span.word_undefinedTSREFProperty {
-       color:#FF8400;
-       font-size:0.95em;
-       font-weight:bold;
-}
-.t3e_codeCompleteBox ul li span.word_userProperty {
-       color:#7c7c7c;
-       font-size:0.95em;
-       font-weight:bold;
-}
-.t3e_descriptionBox{
-       height: 160px;
-       width: 260px;
-       position: absolute;
-       top: 0; left: 0;
-       background-color: #EFEFF4;
-       z-index:190;
-       border:2px solid silver;
-       padding:0px;
-}
-.t3e_toolbar{
-       position:absolute;
-       right:50px;
-       top:0pt;
-       width:200px;
-       /*border: 1px solid #CCCCCC;*/
-}
-.t3e_toolbar_icon{
-       border: 1px solid #CCCCCC;
-       width: 20px;
-       height: 20px;
-       float: left;
-}
-.t3e_codeCompleteBox {
-       position: absolute;
-       top: 0; left: 0;
-       background-color: #EFEFF4;
-       z-index:190;    
-       border:2px solid silver;
-       padding:0px;
-}
-.t3e_codeCompleteBox ul{
-       list-style-type: none;
-       padding:0px;
-       margin:0px;
-       
-}
-.t3e_codeCompleteBox ul li{
-       padding-left:2px;
-       padding-right:2px;
-       font-weight:bold;
-       cursor: pointer; cursor: hand;
-}
-.t3e_codeCompleteBox ul li.active{
-       padding-left:2px;
-       padding-right:2px;
-       font-weight:bold;
-       background-color: #cfcfcf;
-}
-/* around the editor */
-.t3e_wrap {
-       border: 1px solid gray;
-       position: relative;
-       background-color: #EFEFF4;
-       background-image: url('../../../gfx/spinner.gif');
-       background-position: 49% 50%;
-       background-repeat: no-repeat;
-       margin-right: 10px;
-}
-
-.t3e_modalOverlay {
-       position: absolute;
-       top: 0; left: 0;
-       background-color: #EFEFF4;
-       background-image: url('../../../gfx/spinner.gif');
-       background-position: 49% 50%;
-       background-repeat: no-repeat;
-       z-index:200;
-       width: 100%;
-       height: 100%;
-}
-.t3e_autoCompleteBox {
-       position: absolute;
-       top: 0; left: 0;
-       background-color: #EFEFF4;
-       z-index:190;
-       border:2px solid silver;
-       padding:0px;
-}
-.t3e_autoCompleteBox ul{
-       list-style-type: none;
-       padding:0px;
-       margin:0px;
-}
-.t3e_autoCompleteBox ul li{
-       padding-left:2px;
-       padding-right:2px;
-       font-weight:bold;
-       cursor: pointer; cursor: hand;
-}
-.t3e_autoCompleteBox ul li.active{
-       padding-left:2px;
-       padding-right:2px;
-       font-weight:bold;
-       background-color: #cfcfcf;
-}
-.t3e_fullscreen {
-       position: absolute;
-       top: 0;
-       left: 0;
-}
-.t3e_linenum_wrap {
-       width: 4em;
-       position: absolute; top: 0pt; left: 0pt;
-       overflow: hidden;
-}
-.t3e_linenum {
-       font-size: 12px;
-       font-family: monospace;
-       padding: 0 3px 0 0;
-       margin: 0;
-       background-color: #EFEFF4;
-       color: #000;
-       width: 3em;
-       float: left;
-       text-align: right;
-       list-style-type: none;
-}
-.t3e_linenum dt {
-       height: 13px;
-}
-
-.t3e_linenum li {
-       padding: 0 3px 0 0;
-       margin: 0;
-}
-
-.t3e_iframe_wrap {
-       margin: 0 0 0 4em;
-}
-
-.t3e_iframe {
-       display: block;
-       /* width: 100%; */
-       padding: 0;
-}
-
-.t3e_toolbar_wrap {
-       clear: both;
-       width: 100%;
-       font-size: 0.9em;
-       padding-right: 20px;
-}
-
-
-
-
-
-.t3e_statusbar_wrap {
-       clear: both;
-       font-size: 0.9em;
-       padding-left: 3px;
-       padding-top: 3px;
-       background-color:#B8BEC9;
-       background-image: url(../../t3skin/icons/gfx/alt_menu_mainitem_bg.gif);
-       background-position:left top;
-       background-repeat:repeat-x;
-       height: 20px;
-}
-.t3e_statusbar_wrap span {
-       color:#FFFFFF;
-       margin: 3px;
-}
-.t3e_statusbar_item {
-       float: right;
-       height: 16px;
-       border-left: 1px solid gray;
-       padding: 4px 14px 0 14px;
-}
-
-
-.t3e_clickable {
-       cursor:pointer;cursor:hand;
-}
-
-
-.t3e_statusbar_overlay {
-       position: absolute; bottom: 20px; right: 17px;
-       opacity: 0.85;
-       background-color: #EFEFF4;
-       width: 180px;
-       height: 70%;
-       padding: 5px 0px 10px 0px;
-       border-left: 1px solid gray;
-       border-right: 1px solid gray;
-       border-top: 1px solid gray;
-       z-index: 100;
-}
-.t3e_statusbar_overlay#t3e_statusbar_overlay_options {
-       height: 8em;
-}
-.t3e_statusbar_overlay ul {
-       list-style-type: none;
-       padding: 0;
-       margin: 0;
-}
-.t3e_statusbar_overlay ul li {
-       color: #212121;
-       padding: 2px 6px 2px 6px;
-       cursor:pointer;cursor:hand;
-}
-.t3e_statusbar_overlay ul li label {
-       cursor:pointer;cursor:hand;
-}
-.t3e_statusbar_overlay ul li:hover {
-       background-color: #cfcfcf;
-}
-
-#t3e_modalOverlay_help {
-       background-image: none;
-       width: 90%;
-       height: 80%;
-       top: 10%;
-       left: 5%;
-       padding: 10px;
-       border: 1px solid gray;
-}
-
-.t3e_footeritem_active {
-       background-color: #cfcfcf;
-}
diff --git a/typo3/sysext/t3editor/css/t3editor_inner.css b/typo3/sysext/t3editor/css/t3editor_inner.css
deleted file mode 100644 (file)
index 72e85e1..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-
-.editbox {
-       border-width: 0;
-       margin: .0em;
-       padding: 0;
-       font-family: monospace;
-       font-size: 12px;
-       color: black;
-       background-color: #fff;
-       white-space: nowrap;
-}
-
-.editbox p {
-       margin: 0;
-}
-
-
-/*********************************************
- * Syntax highlighting
- *********************************************/
-
-.other { color: black; }
-.ts-operator { color: #0000cc; font-weight: bold; }
-.ts-value { color: #cc0000; }
-.ts-objstr, .keyword, .keyword2, .keyword3, .reserved { color: #0000cc; }
-.ts-value_copy { color: #006600; }
-.ts-value_unset { background-color: #66cc66; }
-.ts-ignored { background-color: #66cc66; }
-.ts-default { background-color: #66cc66; }
-.ts-comment { color: #666; font-style: italic; }
-.ts-condition { background-color: maroon; color: #fff; font-weight: bold; }
-.ts-error { background-color: yellow; border: 1px red dashed; font-weight: bold; }
-.highlight-bracket {background-color: #0c0; color: #fff; }
-.error-bracket {background-color: #d00; color: #fff; }
-
-/* unparsed code */
-pre.code, .editbox {
-       color: #666;
-}
-
index 1f956e5..9510deb 100755 (executable)
@@ -3,7 +3,7 @@
 ########################################################################
 # Extension Manager/Repository config file for ext "t3editor".
 #
-# Auto generated 30-11-2009 00:43
+# Auto generated 01-04-2010 17:50
 #
 # Manual updates:
 # Only the data in the array - everything else is removed by next
@@ -12,7 +12,7 @@
 
 $EM_CONF[$_EXTKEY] = array(
        'title' => 'Editor with syntax highlighting',
-       'description' => 'JavaScript-driven editor with syntax highlighting and codecompletion for TS. Based on CodeMirror.',
+       'description' => 'JavaScript-driven editor with syntax highlighting and codecompletion. Based on CodeMirror.',
        'category' => 'be',
        'shy' => 0,
        'dependencies' => '',
@@ -33,12 +33,12 @@ $EM_CONF[$_EXTKEY] = array(
        'author_company' => '',
        'CGLcompliance' => '',
        'CGLcompliance_note' => '',
-       'version' => '1.0.0',
-       '_md5_values_when_last_written' => 'a:35:{s:7:"LICENSE";s:4:"c17d";s:21:"class.tx_t3editor.php";s:4:"fd42";s:17:"ext_localconf.php";s:4:"5241";s:14:"ext_tables.php";s:4:"7918";s:13:"locallang.xml";s:4:"78cc";s:16:"css/t3editor.css";s:4:"524b";s:22:"css/t3editor_inner.css";s:4:"c37c";s:23:"icons/loader_eeeeee.gif";s:4:"83a4";s:17:"jslib/t3editor.js";s:4:"fed9";s:24:"jslib/codemirror/LICENSE";s:4:"2c10";s:23:"jslib/codemirror/README";s:4:"dbd2";s:30:"jslib/codemirror/codemirror.js";s:4:"3e40";s:26:"jslib/codemirror/editor.js";s:4:"4546";s:31:"jslib/codemirror/mirrorframe.js";s:4:"9944";s:28:"jslib/codemirror/parsecss.js";s:4:"beb3";s:34:"jslib/codemirror/parsehtmlmixed.js";s:4:"8cd8";s:35:"jslib/codemirror/parsejavascript.js";s:4:"664b";s:31:"jslib/codemirror/parsesparql.js";s:4:"8286";s:35:"jslib/codemirror/parsetyposcript.js";s:4:"4808";s:28:"jslib/codemirror/parsexml.js";s:4:"a842";s:26:"jslib/codemirror/select.js";s:4:"a9d4";s:32:"jslib/codemirror/stringstream.js";s:4:"c2a6";s:28:"jslib/codemirror/tokenize.js";s:4:"c008";s:38:"jslib/codemirror/tokenizejavascript.js";s:4:"8219";s:38:"jslib/codemirror/tokenizetyposcript.js";s:4:"9f7c";s:24:"jslib/codemirror/undo.js";s:4:"0a32";s:24:"jslib/codemirror/util.js";s:4:"373e";s:43:"jslib/ts_codecompletion/completionresult.js";s:4:"46a9";s:44:"jslib/ts_codecompletion/descriptionPlugin.js";s:4:"5e86";s:43:"jslib/ts_codecompletion/tscodecompletion.js";s:4:"b6ab";s:35:"jslib/ts_codecompletion/tsparser.js";s:4:"136a";s:32:"jslib/ts_codecompletion/tsref.js";s:4:"41b2";s:58:"lib/ts_codecompletion/class.tx_t3editor_codecompletion.php";s:4:"19c8";s:55:"lib/ts_codecompletion/class.tx_t3editor_tsrefloader.php";s:4:"372a";s:15:"tsref/tsref.xml";s:4:"9f05";}',
+       'version' => '1.1.0',
+       '_md5_values_when_last_written' => 'a:45:{s:7:"LICENSE";s:4:"c17d";s:17:"ext_localconf.php";s:4:"8798";s:14:"ext_tables.php";s:4:"7dff";s:13:"locallang.xml";s:4:"78cc";s:29:"classes/class.tx_t3editor.php";s:4:"417a";s:50:"classes/class.tx_t3editor_hooks_tstemplateinfo.php";s:4:"54ce";s:62:"classes/ts_codecompletion/class.tx_t3editor_codecompletion.php";s:4:"19c8";s:59:"classes/ts_codecompletion/class.tx_t3editor_tsrefloader.php";s:4:"f915";s:23:"icons/loader_eeeeee.gif";s:4:"83a4";s:21:"res/css/csscolors.css";s:4:"3845";s:20:"res/css/jscolors.css";s:4:"e5a0";s:24:"res/css/sparqlcolors.css";s:4:"40ba";s:20:"res/css/t3editor.css";s:4:"9fe2";s:26:"res/css/t3editor_inner.css";s:4:"7b52";s:28:"res/css/typoscriptcolors.css";s:4:"e060";s:21:"res/css/xmlcolors.css";s:4:"847a";s:21:"res/jslib/t3editor.js";s:4:"7dd4";s:28:"res/jslib/codemirror/LICENSE";s:4:"d72d";s:27:"res/jslib/codemirror/README";s:4:"3aca";s:34:"res/jslib/codemirror/codemirror.js";s:4:"6742";s:30:"res/jslib/codemirror/editor.js";s:4:"692d";s:33:"res/jslib/codemirror/highlight.js";s:4:"6d23";s:35:"res/jslib/codemirror/mirrorframe.js";s:4:"a016";s:32:"res/jslib/codemirror/parsecss.js";s:4:"0b95";s:34:"res/jslib/codemirror/parsedummy.js";s:4:"b6e9";s:38:"res/jslib/codemirror/parsehtmlmixed.js";s:4:"ce7e";s:39:"res/jslib/codemirror/parsejavascript.js";s:4:"b422";s:35:"res/jslib/codemirror/parsesparql.js";s:4:"f839";s:39:"res/jslib/codemirror/parsetyposcript.js";s:4:"4808";s:32:"res/jslib/codemirror/parsexml.js";s:4:"2fda";s:30:"res/jslib/codemirror/select.js";s:4:"9083";s:36:"res/jslib/codemirror/stringstream.js";s:4:"b65b";s:32:"res/jslib/codemirror/tokenize.js";s:4:"c008";s:42:"res/jslib/codemirror/tokenizejavascript.js";s:4:"628e";s:42:"res/jslib/codemirror/tokenizetyposcript.js";s:4:"9f7c";s:28:"res/jslib/codemirror/undo.js";s:4:"8097";s:28:"res/jslib/codemirror/util.js";s:4:"27a6";s:47:"res/jslib/ts_codecompletion/completionresult.js";s:4:"46a9";s:48:"res/jslib/ts_codecompletion/descriptionPlugin.js";s:4:"5e86";s:47:"res/jslib/ts_codecompletion/tscodecompletion.js";s:4:"8e81";s:39:"res/jslib/ts_codecompletion/tsparser.js";s:4:"5c80";s:36:"res/jslib/ts_codecompletion/tsref.js";s:4:"1a15";s:48:"res/jslib/tx_tstemplateinfo/tx_tstemplateinfo.js";s:4:"52c6";s:27:"res/templates/t3editor.html";s:4:"4133";s:19:"res/tsref/tsref.xml";s:4:"3bb5";}',
        'constraints' => array(
                'depends' => array(
                        'php' => '5.1.0-0.0.0',
-                       'typo3' => '4.3.0-0.0.0',
+                       'typo3' => '4.4.0-4.4.99',
                ),
                'conflicts' => array(
                ),
index a4ee6e9..d18fb9a 100644 (file)
@@ -1,7 +1,15 @@
 <?php
 if (!defined ('TYPO3_MODE'))   die ('Access denied.');
 
-// Define hooks:
-$TYPO3_CONF_VARS['SC_OPTIONS']['typo3/template.php']['preStartPageHook'][] = 'EXT:t3editor/class.tx_t3editor.php:&tx_t3editor->preStartPageHook';
-$TYPO3_CONF_VARS['SC_OPTIONS']['ext/tstemplate_info/class.tx_tstemplateinfo.php']['postOutputProcessingHook'][] = 'EXT:t3editor/class.tx_t3editor.php:&tx_t3editor->postOutputProcessingHook';
+if (TYPO3_MODE == 'BE') {
+               // register hooks for tstemplate module
+       $TYPO3_CONF_VARS['SC_OPTIONS']['typo3/template.php']['preStartPageHook'][] =
+               'EXT:t3editor/classes/class.tx_t3editor_hooks_tstemplateinfo.php:&tx_t3editor_hooks_tstemplateinfo->preStartPageHook';
+       $TYPO3_CONF_VARS['SC_OPTIONS']['ext/tstemplate_info/class.tx_tstemplateinfo.php']['postOutputProcessingHook'][] =
+               'EXT:t3editor/classes/class.tx_t3editor_hooks_tstemplateinfo.php:&tx_t3editor_hooks_tstemplateinfo->postOutputProcessingHook';
+
+       $TYPO3_CONF_VARS['SC_OPTIONS']['ext/t3editor/classes/class.tx_t3editor.php']['ajaxSaveCode']['tx_tstemplateinfo'] =
+               'EXT:t3editor/classes/class.tx_t3editor_hooks_tstemplateinfo.php:&tx_t3editor_hooks_tstemplateinfo->save';
+}
+
 ?>
\ No newline at end of file
index 1e3c3f2..90c0151 100644 (file)
@@ -5,10 +5,10 @@ if (!defined('TYPO3_MODE')) {
 
 if (TYPO3_MODE == 'BE') {
        // Register AJAX handlers:
-       $TYPO3_CONF_VARS['BE']['AJAX']['tx_t3editor::saveCode'] = 'EXT:t3editor/class.tx_t3editor.php:tx_t3editor->saveCode';
-       $TYPO3_CONF_VARS['BE']['AJAX']['tx_t3editor::getPlugins'] = 'EXT:t3editor/class.tx_t3editor.php:tx_t3editor->getPlugins';
-       $TYPO3_CONF_VARS['BE']['AJAX']['tx_t3editor_TSrefLoader::getTypes'] = 'EXT:t3editor/lib/ts_codecompletion/class.tx_t3editor_tsrefloader.php:tx_t3editor_TSrefLoader->processAjaxRequest';
-       $TYPO3_CONF_VARS['BE']['AJAX']['tx_t3editor_TSrefLoader::getDescription'] = 'EXT:t3editor/lib/ts_codecompletion/class.tx_t3editor_tsrefloader.php:tx_t3editor_TSrefLoader->processAjaxRequest';
-       $TYPO3_CONF_VARS['BE']['AJAX']['tx_t3editor_codecompletion::loadTemplates'] = 'EXT:t3editor/lib/ts_codecompletion/class.tx_t3editor_codecompletion.php:tx_t3editor_codecompletion->processAjaxRequest';
+       $TYPO3_CONF_VARS['BE']['AJAX']['tx_t3editor::saveCode'] = 'EXT:t3editor/classes/class.tx_t3editor.php:tx_t3editor->ajaxSaveCode';
+       $TYPO3_CONF_VARS['BE']['AJAX']['tx_t3editor::getPlugins'] = 'EXT:t3editor/classes/class.tx_t3editor.php:tx_t3editor->getPlugins';
+       $TYPO3_CONF_VARS['BE']['AJAX']['tx_t3editor_TSrefLoader::getTypes'] = 'EXT:t3editor/classes/ts_codecompletion/class.tx_t3editor_tsrefloader.php:tx_t3editor_TSrefLoader->processAjaxRequest';
+       $TYPO3_CONF_VARS['BE']['AJAX']['tx_t3editor_TSrefLoader::getDescription'] = 'EXT:t3editor/classes/ts_codecompletion/class.tx_t3editor_tsrefloader.php:tx_t3editor_TSrefLoader->processAjaxRequest';
+       $TYPO3_CONF_VARS['BE']['AJAX']['tx_t3editor_codecompletion::loadTemplates'] = 'EXT:t3editor/classes/ts_codecompletion/class.tx_t3editor_codecompletion.php:tx_t3editor_codecompletion->processAjaxRequest';
 }
 ?>
\ No newline at end of file
diff --git a/typo3/sysext/t3editor/jslib/codemirror/LICENSE b/typo3/sysext/t3editor/jslib/codemirror/LICENSE
deleted file mode 100644 (file)
index 12134c0..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
- Copyright (c) 2007 Marijn Haverbeke
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any
- damages arising from the use of this software.
-
- Permission is granted to anyone to use this software for any
- purpose, including commercial applications, and to alter it and
- redistribute it freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must
-    not claim that you wrote the original software. If you use this
-    software in a product, an acknowledgment in the product
-    documentation would be appreciated but is not required.
-
- 2. Altered source versions must be plainly marked as such, and must
-    not be misrepresented as being the original software.
-
- 3. This notice may not be removed or altered from any source
-    distribution.
-
- Marijn Haverbeke
- marijnh at gmail
diff --git a/typo3/sysext/t3editor/jslib/codemirror/README b/typo3/sysext/t3editor/jslib/codemirror/README
deleted file mode 100644 (file)
index 9d6a70f..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-The t3editor is based on the CodeMirror-project by Marijn Haverbeke (http://marijn.haverbeke.nl/codemirror/)
-
-Currently the release 0.60 is used. 
-To use the CodeMirror for the t3editor some changes were needed.  The file "typo3/sysext/t3editor/jslib/patch.codemirror.diff" contains a patch to apply the needed changes in the codemirror source.
-
-See the LICENSE file for the CodeMirror license.
-All files in this folder (typo3/sysext/t3editor/jslib/codemirror/) are part of or based on the CodeMirror and therefore licened under the CodeMirror license.
-
-t3editor itself is part of TYPO3 and therefore licened under GPL (as TYPO3 is).
-
-
-thanks,
-
-  Tobias Liebig
-  mail(at)etobi.de
-
diff --git a/typo3/sysext/t3editor/jslib/codemirror/codemirror.js b/typo3/sysext/t3editor/jslib/codemirror/codemirror.js
deleted file mode 100644 (file)
index 55bb8f5..0000000
+++ /dev/null
@@ -1,220 +0,0 @@
-/* CodeMirror main module
- *
- * Implements the CodeMirror constructor and prototype, which take care
- * of initializing the editor frame, and providing the outside interface.
- */
-
-// The CodeMirrorConfig object is used to specify a default
-// configuration. If you specify such an object before loading this
-// file, the values you put into it will override the defaults given
-// below. You can also assign to it after loading.
-var CodeMirrorConfig = window.CodeMirrorConfig || {};
-
-var CodeMirror = (function(){
-  function setDefaults(object, defaults) {
-    for (var option in defaults) {
-      if (!object.hasOwnProperty(option))
-        object[option] = defaults[option];
-    }
-  }
-  function forEach(array, action) {
-    for (var i = 0; i < array.length; i++)
-      action(array[i]);
-  }
-
-  // These default options can be overridden by passing a set of
-  // options to a specific CodeMirror constructor. See manual.html for
-  // their meaning.
-  setDefaults(CodeMirrorConfig, {
-    stylesheet: "",
-    path: "",
-    parserfile: [],
-    basefiles: ["util.js", "stringstream.js", "select.js", "undo.js", "editor.js", "tokenize.js"],
-    linesPerPass: 15,
-    passDelay: 200,
-    continuousScanning: false,
-    saveFunction: null,
-    onChange: null,
-    undoDepth: 20,
-    undoDelay: 800,
-    disableSpellcheck: true,
-    textWrapping: true,
-    readOnly: false,
-    width: "100%",
-    height: "300px",
-    autoMatchParens: false,
-    parserConfig: null,
-    outerEditor: null,
-    dumbTabs: false,
-    activeTokens: null,
-    cursorActivity: null
-  });
-
-  function CodeMirror(place, options) {
-    // Use passed options, if any, to override defaults.
-    this.options = options = options || {};
-    setDefaults(options, CodeMirrorConfig);
-
-    var frame = this.frame = document.createElement("IFRAME");
-    frame.src = "javascript:false;";
-    frame.style.border = "0";
-    frame.style.width = options.width;
-    frame.style.height = options.height;
-    // display: block occasionally suppresses some Firefox bugs, so we
-    // always add it, redundant as it sounds.
-    frame.style.display = "block";
-
-    if (place.appendChild)
-      place.appendChild(frame);
-    else
-      place(frame);
-
-    // Link back to this object, so that the editor can fetch options
-    // and add a reference to itself.
-    frame.CodeMirror = this;
-    this.win = frame.contentWindow;
-
-    if (typeof options.parserfile == "string")
-      options.parserfile = [options.parserfile];
-    if (typeof options.stylesheet == "string")
-      options.stylesheet = [options.stylesheet];
-
-    var html = ["<html><head>"];
-    forEach(options.stylesheet, function(file) {
-      html.push("<link rel=\"stylesheet\" type=\"text/css\" href=\"" + file + "\"/>");
-    });
-    forEach(options.basefiles.concat(options.parserfile), function(file) {
-      html.push("<script type=\"text/javascript\" src=\"" + options.path + file + "\"></script>");
-    });
-    html.push("</head><body style=\"border-width: 0;\" class=\"editbox\" spellcheck=\"" +
-              (options.disableSpellcheck ? "false" : "true") + "\"></body></html>");
-
-    var doc = this.win.document;
-    doc.open();
-    doc.write(html.join(""));
-    doc.close();
-  }
-
-  CodeMirror.prototype = {
-    getCode: function() {return this.editor.getCode();},
-    setCode: function(code) {this.editor.importCode(code);},
-    selection: function() {return this.editor.selectedText();},
-    reindent: function() {this.editor.reindent();},
-
-    focus: function() {
-      this.win.focus();
-      if (this.editor.selectionSnapshot) // IE hack
-        this.win.select.selectCoords(this.win, this.editor.selectionSnapshot);
-    },
-    replaceSelection: function(text) {
-      this.focus();
-      this.editor.replaceSelection(text);
-      return true;
-    },
-    replaceChars: function(text, start, end) {
-      this.editor.replaceChars(text, start, end);
-    },
-    getSearchCursor: function(string, fromCursor) {
-      return this.editor.getSearchCursor(string, fromCursor);
-    },
-
-    cursorPosition: function(start) {
-      if (this.win.select.ie_selection) this.focus();
-      return this.editor.cursorPosition(start);
-    },
-    firstLine: function() {return this.editor.firstLine();},
-    lastLine: function() {return this.editor.lastLine();},
-    nextLine: function(line) {return this.editor.nextLine(line);},
-    prevLine: function(line) {return this.editor.prevLine(line);},
-    lineContent: function(line) {return this.editor.lineContent(line);},
-    setLineContent: function(line, content) {this.editor.setLineContent(line, content);},
-    insertIntoLine: function(line, position, content) {this.editor.insertIntoLine(line, position, content);},
-    selectLines: function(startLine, startOffset, endLine, endOffset) {
-      this.win.focus();
-      this.editor.selectLines(startLine, startOffset, endLine, endOffset);
-    },
-    nthLine: function(n) {
-      var line = this.firstLine();
-      for (; n > 1 && line !== false; n--)
-        line = this.nextLine(line);
-      return line;
-    },
-    lineNumber: function(line) {
-      var num = 0;
-      while (line !== false) {
-        num++;
-        line = this.prevLine(line);
-      }
-      return num;
-    },
-
-    // Old number-based line interface
-    jumpToLine: function(n) {
-      this.selectLines(this.nthLine(n), 0);
-      this.win.focus();
-    },
-    currentLine: function() {
-      return this.lineNumber(this.cursorPosition().line);
-    }
-  };
-
-  CodeMirror.InvalidLineHandle = {toString: function(){return "CodeMirror.InvalidLineHandle";}};
-
-  CodeMirror.replace = function(element) {
-    if (typeof element == "string")
-      element = document.getElementById(element);
-    return function(newElement) {
-      element.parentNode.replaceChild(newElement, element);
-    };
-  };
-
-  CodeMirror.fromTextArea = function(area, options) {
-    if (typeof area == "string")
-      area = document.getElementById(area);
-
-    options = options || {};
-    if (area.style.width) options.width = area.style.width;
-    if (area.style.height) options.height = area.style.height;
-    if (options.content == null) options.content = area.value;
-
-    if (area.form) {
-      function updateField() {
-        area.value = mirror.getCode();
-      }
-      if (typeof area.form.addEventListener == "function")
-        area.form.addEventListener("submit", updateField, false);
-      else
-        area.form.attachEvent("onsubmit", updateField);
-    }
-
-    function insert(frame) {
-      if (area.nextSibling)
-        area.parentNode.insertBefore(frame, area.nextSibling);
-      else
-        area.parentNode.appendChild(frame);
-    }
-
-    area.style.display = "none";
-    var mirror = new CodeMirror(insert, options);
-    return mirror;
-  };
-
-  CodeMirror.isProbablySupported = function() {
-    // This is rather awful, but can be useful.
-    var match;
-    if (window.opera)
-      return Number(window.opera.version()) >= 9.52;
-    else if (/Apple Computers, Inc/.test(navigator.vendor) && (match = navigator.userAgent.match(/Version\/(\d+(?:\.\d+)?)\./)))
-      return Number(match[1]) >= 3;
-    else if (document.selection && window.ActiveXObject && (match = navigator.userAgent.match(/MSIE (\d+(?:\.\d*)?)\b/)))
-      return Number(match[1]) >= 6;
-    else if (match = navigator.userAgent.match(/gecko\/(\d{8})/i))
-      return Number(match[1]) >= 20050901;
-    else if (/Chrome\//.test(navigator.userAgent))
-      return true;
-    else
-      return null;
-  };
-
-  return CodeMirror;
-})();
diff --git a/typo3/sysext/t3editor/jslib/codemirror/editor.js b/typo3/sysext/t3editor/jslib/codemirror/editor.js
deleted file mode 100644 (file)
index 5fc4119..0000000
+++ /dev/null
@@ -1,1237 +0,0 @@
-/* The Editor object manages the content of the editable frame. It
- * catches events, colours nodes, and indents lines. This file also
- * holds some functions for transforming arbitrary DOM structures into
- * plain sequences of <span> and <br> elements
- */
-
-var safeWhiteSpace, splitSpaces;
-function setWhiteSpaceModel(collapsing) {
-  safeWhiteSpace = collapsing ?
-    // Make sure a string does not contain two consecutive 'collapseable'
-    // whitespace characters.
-    function(n) {
-      var buffer = [], nb = true;
-      for (; n > 0; n--) {
-        buffer.push((nb || n == 1) ? nbsp : " ");
-        nb = !nb;
-      }
-      return buffer.join("");
-    } :
-    function(n) {
-      var buffer = [];
-      for (; n > 0; n--) buffer.push(" ");
-      return buffer.join("");
-    };
-  splitSpaces = collapsing ?
-    // Create a set of white-space characters that will not be collapsed
-    // by the browser, but will not break text-wrapping either.
-    function(string) {
-      if (string.charAt(0) == " ") string = nbsp + string.slice(1);
-      return string.replace(/[\t \u00a0]{2,}/g, function(s) {return safeWhiteSpace(s.length);});
-    } :
-    function(string) {return string;};
-}
-
-function makePartSpan(value, doc) {
-  var text = value;
-  if (value.nodeType == 3) text = value.nodeValue;
-  else value = doc.createTextNode(text);
-
-  var span = doc.createElement("SPAN");
-  span.isPart = true;
-  span.appendChild(value);
-  span.currentText = text;
-  return span;
-}
-
-var Editor = (function(){
-  // The HTML elements whose content should be suffixed by a newline
-  // when converting them to flat text.
-  var newlineElements = {"P": true, "DIV": true, "LI": true};
-
-  function asEditorLines(string) {
-    return splitSpaces(string.replace(/\t/g, "  ").replace(/\u00a0/g, " ")).replace(/\r\n?/g, "\n").split("\n");
-  }
-
-  var internetExplorer = document.selection && window.ActiveXObject && /MSIE/.test(navigator.userAgent);
-
-  // Helper function for traverseDOM. Flattens an arbitrary DOM node
-  // into an array of textnodes and <br> tags.
-  function simplifyDOM(root) {
-    var doc = root.ownerDocument;
-    var result = [];
-    var leaving = false;
-
-    function simplifyNode(node) {
-      if (node.nodeType == 3) {
-        var text = node.nodeValue = splitSpaces(node.nodeValue.replace(/[\n\r]/g, ""));
-        if (text.length) leaving = false;
-        result.push(node);
-      }
-      else if (node.nodeName == "BR" && node.childNodes.length == 0) {
-        leaving = true;
-        result.push(node);
-      }
-      else {
-        forEach(node.childNodes, simplifyNode);
-        if (!leaving && newlineElements.hasOwnProperty(node.nodeName)) {
-          leaving = true;
-          result.push(doc.createElement("BR"));
-        }
-      }
-    }
-
-    simplifyNode(root);
-    return result;
-  }
-
-  // Creates a MochiKit-style iterator that goes over a series of DOM
-  // nodes. The values it yields are strings, the textual content of
-  // the nodes. It makes sure that all nodes up to and including the
-  // one whose text is being yielded have been 'normalized' to be just
-  // <span> and <br> elements.
-  // See the story.html file for some short remarks about the use of
-  // continuation-passing style in this iterator.
-  function traverseDOM(start){
-    function yield(value, c){cc = c; return value;}
-    function push(fun, arg, c){return function(){return fun(arg, c);};}
-    function stop(){cc = stop; throw StopIteration;};
-    var cc = push(scanNode, start, stop);
-    var owner = start.ownerDocument;
-    var nodeQueue = [];
-
-    // Create a function that can be used to insert nodes after the
-    // one given as argument.
-    function pointAt(node){
-      var parent = node.parentNode;
-      var next = node.nextSibling;
-      return function(newnode) {
-        parent.insertBefore(newnode, next);
-      };
-    }
-    var point = null;
-
-    // Insert a normalized node at the current point. If it is a text
-    // node, wrap it in a <span>, and give that span a currentText
-    // property -- this is used to cache the nodeValue, because
-    // directly accessing nodeValue is horribly slow on some browsers.
-    // The dirty property is used by the highlighter to determine
-    // which parts of the document have to be re-highlighted.
-    function insertPart(part){
-      var text = "\n";
-      if (part.nodeType == 3) {
-        select.snapshotChanged();
-        part = makePartSpan(part, owner);
-        text = part.currentText;
-      }
-      part.dirty = true;
-      nodeQueue.push(part);
-      point(part);
-      return text;
-    }
-
-    // Extract the text and newlines from a DOM node, insert them into
-    // the document, and yield the textual content. Used to replace
-    // non-normalized nodes.
-    function writeNode(node, c){
-      var toYield = [];
-      forEach(simplifyDOM(node), function(part) {
-        toYield.push(insertPart(part));
-      });
-      return yield(toYield.join(""), c);
-    }
-
-    // Check whether a node is a normalized <span> element.
-    function partNode(node){
-      if (node.nodeName == "SPAN" && node.childNodes.length == 1 && node.firstChild.nodeType == 3 && node.isPart) {
-        node.currentText = node.firstChild.nodeValue;
-        return !/[\n\t\r]/.test(node.currentText);
-      }
-      return false;
-    }
-
-    // Handle a node. Add its successor to the continuation if there
-    // is one, find out whether the node is normalized. If it is,
-    // yield its content, otherwise, normalize it (writeNode will take
-    // care of yielding).
-    function scanNode(node, c){
-      if (node.nextSibling)
-        c = push(scanNode, node.nextSibling, c);
-
-      if (partNode(node)){
-        nodeQueue.push(node);
-        return yield(node.currentText, c);
-      }
-      else if (node.nodeName == "BR") {
-        nodeQueue.push(node);
-        return yield("\n", c);
-      }
-      else {
-        point = pointAt(node);
-        removeElement(node);
-        return writeNode(node, c);
-      }
-    }
-
-    // MochiKit iterators are objects with a next function that
-    // returns the next value or throws StopIteration when there are
-    // no more values.
-    return {next: function(){return cc();}, nodes: nodeQueue};
-  }
-
-  // Determine the text size of a processed node.
-  function nodeSize(node) {
-    if (node.nodeName == "BR")
-      return 1;
-    else
-      return node.currentText.length;
-  }
-
-  // Search backwards through the top-level nodes until the next BR or
-  // the start of the frame.
-  function startOfLine(node) {
-    while (node && node.nodeName != "BR") node = node.previousSibling;
-    return node;
-  }
-  function endOfLine(node, container) {
-    if (!node) node = container.firstChild;
-    else if (node.nodeName == "BR") node = node.nextSibling;
-    while (node && node.nodeName != "BR") node = node.nextSibling;
-    return node;
-  }
-
-  function cleanText(text) {
-    return text.replace(/\u00a0/g, " ");
-  }
-
-  // Client interface for searching the content of the editor. Create
-  // these by calling CodeMirror.getSearchCursor. To use, call
-  // findNext on the resulting object -- this returns a boolean
-  // indicating whether anything was found, and can be called again to
-  // skip to the next find. Use the select and replace methods to
-  // actually do something with the found locations.
-  function SearchCursor(editor, string, fromCursor) {
-    this.editor = editor;
-    this.history = editor.history;
-    this.history.commit();
-
-    // Are we currently at an occurrence of the search string?
-    this.atOccurrence = false;
-    // The object stores a set of nodes coming after its current
-    // position, so that when the current point is taken out of the
-    // DOM tree, we can still try to continue.
-    this.fallbackSize = 15;
-    var cursor;
-    // Start from the cursor when specified and a cursor can be found.
-    if (fromCursor && (cursor = select.cursorPos(this.editor.container))) {
-      this.line = cursor.node;
-      this.offset = cursor.offset;
-    }
-    else {
-      this.line = null;
-      this.offset = 0;
-    }
-    this.valid = !!string;
-
-    // Create a matcher function based on the kind of string we have.
-    var target = string.split("\n"), self = this;;
-    this.matches = (target.length == 1) ?
-      // For one-line strings, searching can be done simply by calling
-      // indexOf on the current line.
-      function() {
-        var match = cleanText(self.history.textAfter(self.line).slice(self.offset)).indexOf(string);
-        if (match > -1)
-          return {from: {node: self.line, offset: self.offset + match},
-                  to: {node: self.line, offset: self.offset + match + string.length}};
-      } :
-      // Multi-line strings require internal iteration over lines, and
-      // some clunky checks to make sure the first match ends at the
-      // end of the line and the last match starts at the start.
-      function() {
-        var firstLine = cleanText(self.history.textAfter(self.line).slice(self.offset));
-        var match = firstLine.lastIndexOf(target[0]);
-        if (match == -1 || match != firstLine.length - target[0].length)
-          return false;
-        var startOffset = self.offset + match;
-
-        var line = self.history.nodeAfter(self.line);
-        for (var i = 1; i < target.length - 1; i++) {
-          if (cleanText(self.history.textAfter(line)) != target[i])
-            return false;
-          line = self.history.nodeAfter(line);
-        }
-
-        if (cleanText(self.history.textAfter(line)).indexOf(target[target.length - 1]) != 0)
-          return false;
-
-        return {from: {node: self.line, offset: startOffset},
-                to: {node: line, offset: target[target.length - 1].length}};
-      };
-  }
-
-  SearchCursor.prototype = {
-    findNext: function() {
-      if (!this.valid) return false;
-      this.atOccurrence = false;
-      var self = this;
-
-      // Go back to the start of the document if the current line is
-      // no longer in the DOM tree.
-      if (this.line && !this.line.parentNode) {
-        this.line = null;
-        this.offset = 0;
-      }
-
-      // Set the cursor's position one character after the given
-      // position.
-      function saveAfter(pos) {
-        if (self.history.textAfter(pos.node).length < pos.offset) {
-          self.line = pos.node;
-          self.offset = pos.offset + 1;
-        }
-        else {
-          self.line = self.history.nodeAfter(pos.node);
-          self.offset = 0;
-        }
-      }
-
-      while (true) {
-        var match = this.matches();
-        // Found the search string.
-        if (match) {
-          this.atOccurrence = match;
-          saveAfter(match.from);
-          return true;
-        }
-        this.line = this.history.nodeAfter(this.line);
-        this.offset = 0;
-        // End of document.
-        if (!this.line) {
-          this.valid = false;
-          return false;
-        }
-      }
-    },
-
-    select: function() {
-      if (this.atOccurrence) {
-        select.setCursorPos(this.editor.container, this.atOccurrence.from, this.atOccurrence.to);
-        select.scrollToCursor(this.editor.container);
-      }
-    },
-
-    replace: function(string) {
-      if (this.atOccurrence) {
-        var end = this.editor.replaceRange(this.atOccurrence.from, this.atOccurrence.to, string);
-        this.line = end.node;
-        this.offset = end.offset;
-        this.atOccurrence = false;
-      }
-    }
-  };
-
-  // The Editor object is the main inside-the-iframe interface.
-  function Editor(options) {
-    this.options = options;
-    this.parent = parent;
-    this.doc = document;
-    this.container = this.doc.body;
-    this.win = window;
-    this.history = new History(this.container, options.undoDepth, options.undoDelay,
-                               this, options.onChange);
-    var self = this;
-
-    if (!Editor.Parser)
-      throw "No parser loaded.";
-    if (options.parserConfig && Editor.Parser.configure)
-      Editor.Parser.configure(options.parserConfig);
-
-    if (!options.textWrapping)
-      this.container.style.whiteSpace = "pre";
-    setWhiteSpaceModel(options.textWrapping);
-
-    if (!options.readOnly)
-      select.setCursorPos(this.container, {node: null, offset: 0});
-
-    this.dirty = [];
-    if (options.content)
-      this.importCode(options.content);
-    else // FF acts weird when the editable document is completely empty
-      this.container.appendChild(this.doc.createElement("BR"));
-
-    if (!options.readOnly) {
-      if (options.continuousScanning !== false) {
-        this.scanner = this.documentScanner(options.linesPerPass);
-        this.delayScanning();
-      }
-
-      function setEditable() {
-        // In IE, designMode frames can not run any scripts, so we use
-        // contentEditable instead.
-        if (document.body.contentEditable != undefined && /MSIE/.test(navigator.userAgent))
-          document.body.contentEditable = "true";
-        else
-          document.designMode = "on";
-      }
-
-      // If setting the frame editable fails, try again when the user
-      // focus it (happens when the frame is not visible on
-      // initialisation, in Firefox).
-      try {
-        setEditable();
-      }
-      catch(e) {
-        var focusEvent = addEventHandler(document, "focus", function() {
-          focusEvent();
-          setEditable();
-        }, true);
-      }
-
-      addEventHandler(document, "keydown", method(this, "keyDown"));
-      addEventHandler(document, "keypress", method(this, "keyPress"));
-      addEventHandler(document, "keyup", method(this, "keyUp"));
-
-      function cursorActivity() {self.cursorActivity(false);}
-      addEventHandler(document.body, "paste", cursorActivity);
-      addEventHandler(document.body, "cut", cursorActivity);
-      addEventHandler(document.body, "mouseup", cursorActivity);
-
-      if (options.outerEditor && options.outerEditor.scroll) {
-          addEventHandler(document, "scroll", method(options.outerEditor, "scroll"));
-          addEventHandler(window, "scroll", method(options.outerEditor, "scroll"));
-      }
-      if (options.outerEditor && options.outerEditor.click) {
-          addEventHandler(document, "click", method(options.outerEditor, "click"));
-      }
-
-
-      if (this.options.autoMatchParens)
-        addEventHandler(document.body, "click", method(this, "scheduleParenBlink"));
-    }
-  }
-
-  function isSafeKey(code) {
-    return (code >= 16 && code <= 18) || // shift, control, alt
-           (code >= 33 && code <= 40); // arrows, home, end
-  }
-
-  Editor.prototype = {
-    // Import a piece of code into the editor.
-    importCode: function(code) {
-      this.history.push(null, null, asEditorLines(code));
-      this.history.reset();
-
-      if (this.options.outerEditor && this.options.outerEditor.updateLinenum) {
-          this.options.outerEditor.updateLinenum();
-      }
-
-    },
-
-    // Extract the code from the editor.
-    getCode: function() {
-      if (!this.container.firstChild)
-        return "";
-
-      var accum = [];
-      select.markSelection(this.win);
-      forEach(traverseDOM(this.container.firstChild), method(accum, "push"));
-      select.selectMarked();
-      return cleanText(accum.join(""));
-    },
-
-    checkLine: function(node) {
-      if (node === false || !(node == null || node.parentNode == this.container))
-        throw parent.CodeMirror.InvalidLineHandle;
-    },
-
-    cursorPosition: function(start) {
-      if (start == null) start = true;
-      var pos = select.cursorPos(this.container, start);
-      if (pos) return {line: pos.node, character: pos.offset};
-      else return {line: null, character: 0};
-    },
-
-    firstLine: function() {
-      return null;
-    },
-
-    lastLine: function() {
-      if (this.container.lastChild) return startOfLine(this.container.lastChild);
-      else return null;
-    },
-
-    nextLine: function(line) {
-      this.checkLine(line);
-      var end = endOfLine(line ? line.nextSibling : this.container.firstChild, this.container);
-      return end || false;
-    },
-
-    prevLine: function(line) {
-      this.checkLine(line);
-      if (line == null) return false;
-      return startOfLine(line.previousSibling);
-    },
-
-    selectLines: function(startLine, startOffset, endLine, endOffset) {
-      this.checkLine(startLine);
-      var start = {node: startLine, offset: startOffset}, end = null;
-      if (endOffset !== undefined) {
-        this.checkLine(endLine);
-        end = {node: endLine, offset: endOffset};
-      }
-      select.setCursorPos(this.container, start, end);
-    },
-
-    lineContent: function(line) {
-      this.checkLine(line);
-      var accum = [];
-      for (line = line ? line.nextSibling : this.container.firstChild;
-           line && line.nodeName != "BR"; line = line.nextSibling)
-        accum.push(line.innerText || line.textContent || line.nodeValue || "");
-      return cleanText(accum.join(""));
-    },
-
-    setLineContent: function(line, content) {
-      this.history.commit();
-      this.replaceRange({node: line, offset: 0},
-                        {node: line, offset: this.history.textAfter(line).length},
-                        content);
-      this.addDirtyNode(line);
-      this.scheduleHighlight();
-    },
-
-    insertIntoLine: function(line, position, content) {
-      var before = null;
-      if (position == "end") {
-        before = endOfLine(line ? line.nextSibling : this.container.firstChild, this.container);
-      }
-      else {
-        for (var cur = line ? line.nextSibling : this.container.firstChild; cur; cur = cur.nextSibling) {
-          if (position == 0) {
-            before = cur;
-            break;
-          }
-          var text = (cur.innerText || cur.textContent || cur.nodeValue || "");
-          if (text.length > position) {
-            before = cur.nextSibling;
-            content = text.slice(0, position) + content + text.slice(position);
-            removeElement(cur);
-            break;
-          }
-          position -= text.length;
-        }
-      }
-
-      var lines = asEditorLines(content), doc = this.container.ownerDocument;
-      for (var i = 0; i < lines.length; i++) {
-        if (i > 0) this.container.insertBefore(doc.createElement("BR"), before);
-        this.container.insertBefore(makePartSpan(lines[i], doc), before);
-      }
-      this.addDirtyNode(line);
-      this.scheduleHighlight();
-    },
-
-    // Retrieve the selected text.
-    selectedText: function() {
-      var h = this.history;
-      h.commit();
-
-      var start = select.cursorPos(this.container, true),
-          end = select.cursorPos(this.container, false);
-      if (!start || !end) return "";
-
-      if (start.node == end.node)
-        return h.textAfter(start.node).slice(start.offset, end.offset);
-
-      var text = [h.textAfter(start.node).slice(start.offset)];
-      for (pos = h.nodeAfter(start.node); pos != end.node; pos = h.nodeAfter(pos))
-        text.push(h.textAfter(pos));
-      text.push(h.textAfter(end.node).slice(0, end.offset));
-      return cleanText(text.join("\n"));
-    },
-
-    // Replace the selection with another piece of text.
-    replaceSelection: function(text) {
-      this.history.commit();
-      var start = select.cursorPos(this.container, true),
-          end = select.cursorPos(this.container, false);
-      if (!start || !end) return;
-
-      end = this.replaceRange(start, end, text);
-      select.setCursorPos(this.container, start, end);
-    },
-
-    replaceRange: function(from, to, text) {
-      var lines = asEditorLines(text);
-      lines[0] = this.history.textAfter(from.node).slice(0, from.offset) + lines[0];
-      var lastLine = lines[lines.length - 1];
-      lines[lines.length - 1] = lastLine + this.history.textAfter(to.node).slice(to.offset);
-      var end = this.history.nodeAfter(to.node);
-      this.history.push(from.node, end, lines);
-      return {node: this.history.nodeBefore(end),
-              offset: lastLine.length};
-    },
-
-    getSearchCursor: function(string, fromCursor) {
-      return new SearchCursor(this, string, fromCursor);
-    },
-
-    // Re-indent the whole buffer
-    reindent: function() {
-      if (this.container.firstChild)
-        this.indentRegion(null, this.container.lastChild);
-    },
-
-    // Intercept enter and tab, and assign their new functions.
-    keyDown: function(event) {
-      // Don't scan when the user is typing.
-      this.delayScanning();
-
-      if (
-            this.options.outerEditor 
-            && this.options.outerEditor.checkTextModified
-            && !isSafeKey(event.keyCode)
-            && !event.ctrlKey ) {
-                    this.options.outerEditor.checkTextModified();
-      }
-
-      // Schedule a paren-highlight event, if configured.
-      if (this.options.autoMatchParens)
-        this.scheduleParenBlink();
-
-      if (event.keyCode == 13) { // enter
-        if (event.ctrlKey) {
-          this.reparseBuffer();
-        }
-        else {
-          select.insertNewlineAtCursor(this.win);
-          this.indentAtCursor();
-          select.scrollToCursor(this.container);
-          if (this.options.outerEditor && this.options.outerEditor.updateLinenum) {
-              this.options.outerEditor.updateLinenum();
-          }
-
-        }
-        event.stop();
-      }
-      else if (event.keyCode == 9) { // tab
-        this.handleTab(!event.ctrlKey && !event.shiftKey);
-        event.stop();
-      }
-      else if (event.metaKey && !event.shiftKey && (event.keyCode == 37 || event.keyCode == 39)) { // Meta-left/right
-        var cursor = select.selectionTopNode(this.container);
-        if (cursor === false || !this.container.firstChild) return;
-
-        if (event.keyCode == 37) select.focusAfterNode(startOfLine(cursor), this.container);
-        else {
-          var end = endOfLine(cursor, this.container);
-          select.focusAfterNode(end ? end.previousSibling : this.container.lastChild, this.container);
-        }
-        event.stop();
-      }
-      else if (event.ctrlKey || event.metaKey) {
-        if (event.keyCode == 90 || event.keyCode == 8) { // Z, backspace
-          this.history.undo();
-          event.stop();
-        }
-        else if (event.keyCode == 89) { // Y
-          this.history.redo();
-          event.stop();
-        }
-        else if (event.keyCode == 83 && this.options.saveFunction) { // S
-          this.options.saveFunction();
-          event.stop();
-        }
-        else if (event.keyCode == 122 ) { // F11 toogle fullscreen mode
-            if (this.options.outerEditor && this.options.outerEditor.toggleFullscreen) {
-                this.options.outerEditor.toggleFullscreen();
-                event.stop();
-            }
-        }
-      }
-    },
-
-    // Check for characters that should re-indent the current line,
-    // and prevent Opera from handling enter and tab anyway.
-    keyPress: function(event) {
-      var electric = Editor.Parser.electricChars;
-      // Hack for Opera, and Firefox on OS X, in which stopping a
-      // keydown event does not prevent the associated keypress event
-      // from happening, so we have to cancel enter and tab again
-      // here.
-      if (event.code == 13 || event.code == 9)
-        event.stop();
-      else if ((event.character == "[" || event.character == "]") && event.ctrlKey)
-        event.stop(), this.blinkParens();
-      else if (electric && electric.indexOf(event.character) != -1)
-        this.parent.setTimeout(method(this, "indentAtCursor"), 0);
-    },
-
-    // Mark the node at the cursor dirty when a non-safe key is
-    // released.
-    keyUp: function(event) {
-      this.cursorActivity(isSafeKey(event.keyCode));
-      if (event.keyCode == 46       // Delete
-         || event.keyCode == 13  // Return
-         || event.keyCode == 8) {        // Backspace
-            if (this.options.outerEditor && this.options.outerEditor.updateLinenum) {
-                this.options.outerEditor.updateLinenum();
-            }
-       }
-       if (this.options.outerEditor && this.options.outerEditor.checkBracketAtCursor) {
-             this.options.outerEditor.checkBracketAtCursor();
-       }
-
-    },
-
-    // Indent the line following a given <br>, or null for the first
-    // line. If given a <br> element, this must have been highlighted
-    // so that it has an indentation method. Returns the whitespace
-    // element that has been modified or created (if any).
-    indentLineAfter: function(start, direction) {
-      // whiteSpace is the whitespace span at the start of the line,
-      // or null if there is no such node.
-      var whiteSpace = start ? start.nextSibling : this.container.firstChild;
-      if (whiteSpace && !hasClass(whiteSpace, "whitespace"))
-        whiteSpace = null;
-
-      // Sometimes the start of the line can influence the correct
-      // indentation, so we retrieve it.
-      var firstText = whiteSpace ? whiteSpace.nextSibling : (start ? start.nextSibling : this.container.firstChild);
-      var nextChars = (start && firstText && firstText.currentText) ? firstText.currentText : "";
-
-      // Ask the lexical context for the correct indentation, and
-      // compute how much this differs from the current indentation.
-      var newIndent = 0, curIndent = whiteSpace ? whiteSpace.currentText.length : 0;
-      if (start) newIndent = start.indentation(nextChars, curIndent, direction);
-      else if (Editor.Parser.firstIndentation) newIndent = Editor.Parser.firstIndentation(nextChars, curIndent, direction);
-      var indentDiff = newIndent - curIndent;
-
-      // If there is too much, this is just a matter of shrinking a span.
-      if (indentDiff < 0) {
-        if (newIndent == 0) {
-          if (firstText) select.snapshotMove(whiteSpace.firstChild, firstText.firstChild, 0);
-          removeElement(whiteSpace);
-          whiteSpace = null;
-        }
-        else {
-          select.snapshotMove(whiteSpace.firstChild, whiteSpace.firstChild, indentDiff, true);
-          whiteSpace.currentText = safeWhiteSpace(newIndent);
-          whiteSpace.firstChild.nodeValue = whiteSpace.currentText;
-        }
-      }
-      // Not enough...
-      else if (indentDiff > 0) {
-        // If there is whitespace, we grow it.
-        if (whiteSpace) {
-          whiteSpace.currentText = safeWhiteSpace(newIndent);
-          whiteSpace.firstChild.nodeValue = whiteSpace.currentText;
-        }
-        // Otherwise, we have to add a new whitespace node.
-        else {
-          whiteSpace = makePartSpan(safeWhiteSpace(newIndent), this.doc);
-          whiteSpace.className = "whitespace";
-          if (start) insertAfter(whiteSpace, start);
-          else this.container.insertBefore(whiteSpace, this.container.firstChild);
-        }
-        if (firstText) select.snapshotMove(firstText.firstChild, whiteSpace.firstChild, curIndent, false, true);
-      }
-      if (indentDiff != 0) this.addDirtyNode(start);
-      return whiteSpace;
-    },
-
-    // Re-highlight the selected part of the document.
-    highlightAtCursor: function() {
-      var pos = select.selectionTopNode(this.container, true);
-      var to = select.selectionTopNode(this.container, false);
-      if (pos === false || !to) return;
-      // Skip one node ahead to make sure the cursor itself is
-      // *inside* a highlighted line.
-      if (to.nextSibling) to = to.nextSibling;
-
-      select.markSelection(this.win);
-      var toIsText = to.nodeType == 3;
-      if (!toIsText) to.dirty = true;
-
-      // Highlight lines as long as to is in the document and dirty.
-      while (to.parentNode == this.container && (toIsText || to.dirty)) {
-        var result = this.highlight(pos, 1, true);
-        if (result) pos = result.node;
-        if (!result || result.left) break;
-      }
-      select.selectMarked();
-    },
-
-    // When tab is pressed with text selected, the whole selection is
-    // re-indented, when nothing is selected, the line with the cursor
-    // is re-indented.
-    handleTab: function(direction) {
-      if (this.options.dumbTabs) {
-        select.insertTabAtCursor(this.win);
-      }
-      else if (!select.somethingSelected(this.win)) {
-        this.indentAtCursor(direction);
-      }
-      else {
-        var start = select.selectionTopNode(this.container, true),
-            end = select.selectionTopNode(this.container, false);
-        if (start === false || end === false) return;
-        this.indentRegion(start, end, direction);
-      }
-    },
-
-    // Delay (or initiate) the next paren blink event.
-    scheduleParenBlink: function() {
-      if (this.parenEvent) this.parent.clearTimeout(this.parenEvent);
-      this.parenEvent = this.parent.setTimeout(method(this, "blinkParens"), 300);
-    },
-
-    isNearParsedNode: function(node) {
-      var distance = 0;
-      while (node && (!node.parserFromHere || node.dirty)) {
-        distance += (node.textContent || node.innerText || "-").length;
-        if (distance > 800) return false;
-        node = node.previousSibling;
-      }
-      return true;
-    },
-
-    // Take the token before the cursor. If it contains a character in
-    // '()[]{}', search for the matching paren/brace/bracket, and
-    // highlight them in green for a moment, or red if no proper match
-    // was found.
-    blinkParens: function() {
-      // Clear the event property.
-      if (this.parenEvent) this.parent.clearTimeout(this.parenEvent);
-      this.parenEvent = null;
-
-      // Extract a 'paren' from a piece of text.
-      function paren(node) {
-        if (node.currentText) {
-          var match = node.currentText.match(/^[\s\u00a0]*([\(\)\[\]\{\}])[\s\u00a0]*$/);
-          return match && match[1];
-        }
-      }
-      // Determine the direction a paren is facing.
-      function forward(ch) {
-        return /[\(\[\{]/.test(ch);
-      }
-
-      var ch, self = this, cursor = select.selectionTopNode(this.container, true);
-      if (!cursor || !this.isNearParsedNode(cursor)) return;
-      this.highlightAtCursor();
-      cursor = select.selectionTopNode(this.container, true);
-      if (!cursor || !(ch = paren(cursor))) return;
-      // We only look for tokens with the same className.
-      var className = cursor.className, dir = forward(ch), match = matching[ch];
-
-      // Since parts of the document might not have been properly
-      // highlighted, and it is hard to know in advance which part we
-      // have to scan, we just try, and when we find dirty nodes we
-      // abort, parse them, and re-try.
-      function tryFindMatch() {
-        var stack = [], ch, ok = true;;
-        for (var runner = cursor; runner; runner = dir ? runner.nextSibling : runner.previousSibling) {
-          if (runner.className == className && runner.nodeName == "SPAN" && (ch = paren(runner))) {
-            if (forward(ch) == dir)
-              stack.push(ch);
-            else if (!stack.length)
-              ok = false;
-            else if (stack.pop() != matching[ch])
-              ok = false;
-            if (!stack.length) break;
-          }
-          else if (runner.dirty || runner.nodeName != "SPAN" && runner.nodeName != "BR") {
-            return {node: runner, status: "dirty"};
-          }
-        }
-        return {node: runner, status: runner && ok};
-      }
-      // Temporarily give the relevant nodes a colour.
-      function blink(node, ok) {
-        node.style.fontWeight = "bold";
-        node.style.color = ok ? "#8F8" : "#F88";
-        self.parent.setTimeout(function() {node.style.fontWeight = ""; node.style.color = "";}, 500);
-      }
-
-      while (true) {
-        var found = tryFindMatch();
-        if (found.status == "dirty") {
-          this.highlight(found.node, 1);
-          // Needed because in some corner cases a highlight does not
-          // reach a node.
-          found.node.dirty = false;
-          continue;
-        }
-        else {
-          blink(cursor, found.status);
-          if (found.node) blink(found.node, found.status);
-          break;
-        }
-      }
-    },
-
-    // Adjust the amount of whitespace at the start of the line that
-    // the cursor is on so that it is indented properly.
-    indentAtCursor: function(direction) {
-      if (!this.container.firstChild) return;
-      // The line has to have up-to-date lexical information, so we
-      // highlight it first.
-      this.highlightAtCursor();
-      var cursor = select.selectionTopNode(this.container, false);
-      // If we couldn't determine the place of the cursor,
-      // there's nothing to indent.
-      if (cursor === false)
-        return;
-      var lineStart = startOfLine(cursor);
-
-      if (this.options.outerEditor && this.options.outerEditor.autoCloseBracket) {
-         this.options.outerEditor.autoCloseBracket(lineStart.previousSibling);
-      }
-
-      var whiteSpace = this.indentLineAfter(lineStart, direction);
-      if (cursor == lineStart && whiteSpace)
-          cursor = whiteSpace;
-      // This means the indentation has probably messed up the cursor.
-      if (cursor == whiteSpace)
-        select.focusAfterNode(cursor, this.container);
-    },
-
-    // Indent all lines whose start falls inside of the current
-    // selection.
-    indentRegion: function(current, end, direction) {
-      select.markSelection(this.win);
-      current = startOfLine(current);
-      end = endOfLine(end, this.container);
-
-      do {
-        this.highlight(current);
-        var hl = this.highlight(current, 1);
-        this.indentLineAfter(current, direction);
-        current = hl ? hl.node : null;
-      } while (current != end);
-      select.selectMarked();
-    },
-
-    // Find the node that the cursor is in, mark it as dirty, and make
-    // sure a highlight pass is scheduled.
-    cursorActivity: function(safe) {
-      if (internetExplorer) {
-        this.container.createTextRange().execCommand("unlink");
-        this.selectionSnapshot = select.selectionCoords(this.win);
-      }
-
-      var activity = this.options.cursorActivity;
-      if (!safe || activity) {
-        var cursor = select.selectionTopNode(this.container, false);
-        if (cursor === false || !this.container.firstChild) return;
-        cursor = cursor || this.container.firstChild;
-        if (activity) activity(cursor);
-        if (!safe) {
-          this.scheduleHighlight();
-          this.addDirtyNode(cursor);
-        }
-      }
-    },
-
-    reparseBuffer: function() {
-      forEach(this.container.childNodes, function(node) {node.dirty = true;});
-      if (this.container.firstChild)
-        this.addDirtyNode(this.container.firstChild);
-    },
-
-    // Add a node to the set of dirty nodes, if it isn't already in
-    // there.
-    addDirtyNode: function(node) {
-      node = node || this.container.firstChild;
-      if (!node) return;
-
-      for (var i = 0; i < this.dirty.length; i++)
-        if (this.dirty[i] == node) return;
-
-      if (node.nodeType != 3)
-        node.dirty = true;
-      this.dirty.push(node);
-    },
-
-    // Cause a highlight pass to happen in options.passDelay
-    // milliseconds. Clear the existing timeout, if one exists. This
-    // way, the passes do not happen while the user is typing, and
-    // should as unobtrusive as possible.
-    scheduleHighlight: function() {
-      // Timeouts are routed through the parent window, because on
-      // some browsers designMode windows do not fire timeouts.
-      var self = this;
-      this.parent.clearTimeout(this.highlightTimeout);
-      this.highlightTimeout = this.parent.setTimeout(function(){self.highlightDirty();}, this.options.passDelay);
-    },
-
-    // Fetch one dirty node, and remove it from the dirty set.
-    getDirtyNode: function() {
-      while (this.dirty.length > 0) {
-        var found = this.dirty.pop();
-        // IE8 sometimes throws an unexplainable 'invalid argument'
-        // exception for found.parentNode
-        try {
-          // If the node has been coloured in the meantime, or is no
-          // longer in the document, it should not be returned.
-          while (found && found.parentNode != this.container)
-            found = found.parentNode
-          if (found && (found.dirty || found.nodeType == 3))
-            return found;
-        } catch (e) {}
-      }
-      return null;
-    },
-
-    // Pick dirty nodes, and highlight them, until
-    // options.linesPerPass lines have been highlighted. The highlight
-    // method will continue to next lines as long as it finds dirty
-    // nodes. It returns an object indicating the amount of lines
-    // left, and information about the place where it stopped. If
-    // there are dirty nodes left after this function has spent all
-    // its lines, it shedules another highlight to finish the job.
-    highlightDirty: function(force) {
-      var lines = force ? Infinity : this.options.linesPerPass;
-      if (!this.options.readOnly) select.markSelection(this.win);
-      var start;
-      while (lines > 0 && (start = this.getDirtyNode())){
-        var result = this.highlight(start, lines);
-        if (result) {
-          lines = result.left;
-          if (result.node && result.dirty)
-            this.addDirtyNode(result.node);
-        }
-      }
-      if (!this.options.readOnly) select.selectMarked();
-      if (start)
-        this.scheduleHighlight();
-      return this.dirty.length == 0;
-    },
-
-    // Creates a function that, when called through a timeout, will
-    // continuously re-parse the document.
-    documentScanner: function(linesPer) {
-      var self = this, pos = null;
-      return function() {
-        // If the current node is no longer in the document... oh
-        // well, we start over.
-        if (pos && pos.parentNode != self.container)
-          pos = null;
-        select.markSelection(self.win);
-        var result = self.highlight(pos, linesPer, true);
-        select.selectMarked();
-        var newPos = result ? (result.node && result.node.nextSibling) : null;
-        pos = (pos == newPos) ? null : newPos;
-        self.delayScanning();
-      };
-    },
-
-    // Starts the continuous scanning process for this document after
-    // a given interval.
-    delayScanning: function() {
-      if (this.scanner) {
-        this.parent.clearTimeout(this.documentScan);
-        this.documentScan = this.parent.setTimeout(this.scanner, this.options.continuousScanning);
-      }
-    },
-
-    // The function that does the actual highlighting/colouring (with
-    // help from the parser and the DOM normalizer). Its interface is
-    // rather overcomplicated, because it is used in different
-    // situations: ensuring that a certain line is highlighted, or
-    // highlighting up to X lines starting from a certain point. The
-    // 'from' argument gives the node at which it should start. If
-    // this is null, it will start at the beginning of the frame. When
-    // a number of lines is given with the 'lines' argument, it will
-    // colour no more than that amount. If at any time it comes across
-    // a 'clean' line (no dirty nodes), it will stop, except when
-    // 'cleanLines' is true.
-    highlight: function(from, lines, cleanLines){
-      var container = this.container, self = this, active = this.options.activeTokens, origFrom = from;
-
-      if (!container.firstChild)
-        return;
-      // lines given as null means 'make sure this BR node has up to date parser information'
-      if (lines == null) {
-        if (!from) return;
-        else from = from.previousSibling;
-      }
-      // Backtrack to the first node before from that has a partial
-      // parse stored.
-      while (from && (!from.parserFromHere || from.dirty))
-        from = from.previousSibling;
-      // If we are at the end of the document, do nothing.
-      if (from && !from.nextSibling)
-        return;
-
-      // Check whether a part (<span> node) and the corresponding token
-      // match.
-      function correctPart(token, part){
-        return !part.reduced && part.currentText == token.value && part.className == token.style;
-      }
-      // Shorten the text associated with a part by chopping off
-      // characters from the front. Note that only the currentText
-      // property gets changed. For efficiency reasons, we leave the
-      // nodeValue alone -- we set the reduced flag to indicate that
-      // this part must be replaced.
-      function shortenPart(part, minus){
-        part.currentText = part.currentText.substring(minus);
-        part.reduced = true;
-      }
-      // Create a part corresponding to a given token.
-      function tokenPart(token){
-        var part = makePartSpan(token.value, self.doc);
-        part.className = token.style;
-        return part;
-      }
-
-      // Get the token stream. If from is null, we start with a new
-      // parser from the start of the frame, otherwise a partial parse
-      // is resumed.
-      var traversal = traverseDOM(from ? from.nextSibling : container.firstChild),
-          stream = stringStream(traversal),
-          parsed = from ? from.parserFromHere(stream) : Editor.Parser.make(stream);
-
-      // parts is an interface to make it possible to 'delay' fetching
-      // the next DOM node until we are completely done with the one
-      // before it. This is necessary because often the next node is
-      // not yet available when we want to proceed past the current
-      // one.
-      var parts = {
-        current: null,
-        // Fetch current node.
-        get: function(){
-          if (!this.current)
-            this.current = traversal.nodes.shift();
-          return this.current;
-        },
-        // Advance to the next part (do not fetch it yet).
-        next: function(){
-          this.current = null;
-        },
-        // Remove the current part from the DOM tree, and move to the
-        // next.
-        remove: function(){
-          container.removeChild(this.get());
-          this.current = null;
-        },
-        // Advance to the next part that is not empty, discarding empty
-        // parts.
-        getNonEmpty: function(){
-          var part = this.get();
-          // Allow empty nodes when they are alone on a line, needed
-          // for the FF cursor bug workaround (see select.js,
-          // insertNewlineAtCursor).
-          while (part && part.nodeName == "SPAN" && part.currentText == "") {
-            var old = part;
-            this.remove();
-            part = this.get();
-            // Adjust selection information, if any. See select.js for details.
-            select.snapshotMove(old.firstChild, part.firstChild || part, 0);
-          }
-          return part;
-        }
-      };
-
-      var lineDirty = false, prevLineDirty = true, lineNodes = 0;
-
-      // This forEach loops over the tokens from the parsed stream, and
-      // at the same time uses the parts object to proceed through the
-      // corresponding DOM nodes.
-      forEach(parsed, function(token){
-        var part = parts.getNonEmpty();
-
-        if (token.value == "\n"){
-          // The idea of the two streams actually staying synchronized
-          // is such a long shot that we explicitly check.
-          if (part.nodeName != "BR")
-            throw "Parser out of sync. Expected BR.";
-
-          if (part.dirty || !part.indentation) lineDirty = true;
-          if (lineDirty) self.history.touch(from);
-          from = part;
-
-          // Every <br> gets a copy of the parser state and a lexical
-          // context assigned to it. The first is used to be able to
-          // later resume parsing from this point, the second is used
-          // for indentation.
-          part.parserFromHere = parsed.copy();
-          part.indentation = token.indentation;
-          part.dirty = false;
-
-          // No line argument passed means 'go at least until this node'.
-          if (lines == null && part == origFrom) throw StopIteration;
-
-          // A clean line with more than one node means we are done.
-          // Throwing a StopIteration is the way to break out of a
-          // MochiKit forEach loop.
-          if ((lines !== undefined && --lines <= 0) || (!lineDirty && !prevLineDirty && lineNodes > 1 && !cleanLines))
-            throw StopIteration;
-          prevLineDirty = lineDirty; lineDirty = false; lineNodes = 0;
-          parts.next();
-        }
-        else {
-          if (part.nodeName != "SPAN")
-            throw "Parser out of sync. Expected SPAN.";
-          if (part.dirty)
-            lineDirty = true;
-          lineNodes++;
-
-          // If the part matches the token, we can leave it alone.
-          if (correctPart(token, part)){
-            part.dirty = false;
-            parts.next();
-          }
-          // Otherwise, we have to fix it.
-          else {
-            lineDirty = true;
-            // Insert the correct part.
-            var newPart = tokenPart(token);
-            container.insertBefore(newPart, part);
-            if (active) active(newPart, token, self);
-            var tokensize = token.value.length;
-            var offset = 0;
-            // Eat up parts until the text for this token has been
-            // removed, adjusting the stored selection info (see
-            // select.js) in the process.
-            while (tokensize > 0) {
-              part = parts.get();
-              var partsize = part.currentText.length;
-              select.snapshotReplaceNode(part.firstChild, newPart.firstChild, tokensize, offset);
-              if (partsize > tokensize){
-                shortenPart(part, tokensize);
-                tokensize = 0;
-              }
-              else {
-                tokensize -= partsize;
-                offset += partsize;
-                parts.remove();
-              }
-            }
-          }
-        }
-      });
-      if (lineDirty) this.history.touch(from);
-
-      // The function returns some status information that is used by
-      // hightlightDirty to determine whether and where it has to
-      // continue.
-      return {left: lines,
-              node: parts.get(),
-              dirty: lineDirty};
-    }
-  };
-
-  return Editor;
-})();
-
-addEventHandler(window, "load", function() {
-  var CodeMirror = window.frameElement.CodeMirror;
-  CodeMirror.editor = new Editor(CodeMirror.options);
-  if (CodeMirror.options.initCallback) {
-    this.parent.setTimeout(function(){
-      CodeMirror.options.initCallback(CodeMirror);
-    }, 0);
-  }
-});
diff --git a/typo3/sysext/t3editor/jslib/codemirror/mirrorframe.js b/typo3/sysext/t3editor/jslib/codemirror/mirrorframe.js
deleted file mode 100644 (file)
index 7f6ad1a..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/* Demonstration of embedding CodeMirror in a bigger application. The
- * interface defined here is a mess of prompts and confirms, and
- * should probably not be used in a real project.
- */
-
-function MirrorFrame(place, options) {
-  this.home = document.createElement("DIV");
-  if (place.appendChild)
-    place.appendChild(this.home);
-  else
-    place(this.home);
-
-  var self = this;
-  function makeButton(name, action) {
-    var button = document.createElement("INPUT");
-    button.type = "button";
-    button.value = name;
-    self.home.appendChild(button);
-    button.onclick = function(){self[action].call(self);};
-  }
-
-  makeButton("Search", "search");
-  makeButton("Replace", "replace");
-  makeButton("Current line", "line");
-  makeButton("Jump to line", "jump");
-  makeButton("Insert constructor", "macro");
-  makeButton("Indent all", "reindent");
-
-  this.mirror = new CodeMirror(this.home, options);
-}
-
-MirrorFrame.prototype = {
-  search: function() {
-    var text = prompt("Enter search term:", "");
-    if (!text) return;
-
-    var first = true;
-    do {
-      var cursor = this.mirror.getSearchCursor(text, first);
-      first = false;
-      while (cursor.findNext()) {
-        cursor.select();
-        if (!confirm("Search again?"))
-          return;
-      }
-    } while (confirm("End of document reached. Start over?"));
-  },
-
-  replace: function() {
-    // This is a replace-all, but it is possible to implement a
-    // prompting replace.
-    var from = prompt("Enter search string:", ""), to;
-    if (from) to = prompt("What should it be replaced with?", "");
-    if (to == null) return;
-
-    var cursor = this.mirror.getSearchCursor(from, false);
-    while (cursor.findNext())
-      cursor.replace(to);
-  },
-
-  jump: function() {
-    var line = prompt("Jump to line:", "");
-    if (line && !isNaN(Number(line)))
-      this.mirror.jumpToLine(Number(line));
-  },
-
-  line: function() {
-    alert("The cursor is currently at line " + this.mirror.currentLine());
-    this.mirror.focus();
-  },
-
-  macro: function() {
-    var name = prompt("Name your constructor:", "");
-    if (name)
-      this.mirror.replaceSelection("function " + name + "() {\n  \n}\n\n" + name + ".prototype = {\n  \n};\n");
-  },
-
-  reindent: function() {
-    this.mirror.reindent();
-  }
-};
diff --git a/typo3/sysext/t3editor/jslib/codemirror/parsecss.js b/typo3/sysext/t3editor/jslib/codemirror/parsecss.js
deleted file mode 100644 (file)
index c22f295..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-/* Simple parser for CSS */
-
-var CSSParser = Editor.Parser = (function() {
-  var tokenizeCSS = (function() {
-    function normal(source, setState) {
-      var ch = source.next();
-      if (ch == "@") {
-        source.nextWhile(matcher(/\w/));
-        return "css-at";
-      }
-      else if (ch == "/" && source.equals("*")) {
-        setState(inCComment);
-        return null;
-      }
-      else if (ch == "<" && source.equals("!")) {
-        setState(inSGMLComment);
-        return null;
-      }
-      else if (ch == "=") {
-        return "css-compare";
-      }
-      else if (source.equals("=") && (ch == "~" || ch == "|")) {
-        source.next();
-        return "css-compare";
-      }
-      else if (ch == "\"" || ch == "'") {
-        setState(inString(ch));
-        return null;
-      }
-      else if (ch == "#") {
-        source.nextWhile(matcher(/\w/));
-        return "css-hash";
-      }
-      else if (ch == "!") {
-        source.nextWhile(matcher(/[ \t]/));
-        source.nextWhile(matcher(/\w/));
-        return "css-important";
-      }
-      else if (/\d/.test(ch)) {
-        source.nextWhile(matcher(/[\w.%]/));
-        return "css-unit";
-      }
-      else if (/[,.+>*\/]/.test(ch)) {
-        return "css-select-op";
-      }
-      else if (/[;{}:\[\]]/.test(ch)) {
-        return "css-punctuation";
-      }
-      else {
-        source.nextWhile(matcher(/[\w\\\-_]/));
-        return "css-identifier";
-      }
-    }
-
-    function inCComment(source, setState) {
-      var maybeEnd = false;
-      while (!source.endOfLine()) {
-        var ch = source.next();
-        if (maybeEnd && ch == "/") {
-          setState(normal);
-          break;
-        }
-        maybeEnd = (ch == "*");
-      }
-      return "css-comment";
-    }
-
-    function inSGMLComment(source, setState) {
-      var dashes = 0;
-      while (!source.endOfLine()) {
-        var ch = source.next();
-        if (dashes >= 2 && ch == ">") {
-          setState(normal);
-          break;
-        }
-        dashes = (ch == "-") ? dashes + 1 : 0;
-      }
-      return "css-comment";
-    }
-
-    function inString(quote) {
-      return function(source, setState) {
-        var escaped = false;
-        while (!source.endOfLine()) {
-          var ch = source.next();
-          if (ch == quote && !escaped)
-            break;
-          escaped = !escaped && ch == "\\";
-        }
-        if (!escaped)
-          setState(normal);
-        return "css-string";
-      };
-    }
-
-    return function(source, startState) {
-      return tokenizer(source, startState || normal);
-    };
-  })();
-
-  function indentCSS(inBraces, inRule, base) {
-    return function(nextChars) {
-      if (!inBraces || /^\}/.test(nextChars)) return base;
-      else if (inRule) return base + 4;
-      else return base + 2;
-    };
-  }
-
-  // This is a very simplistic parser -- since CSS does not really
-  // nest, it works acceptably well, but some nicer colouroing could
-  // be provided with a more complicated parser.
-  function parseCSS(source, basecolumn) {
-    basecolumn = basecolumn || 0;
-    var tokens = tokenizeCSS(source);
-    var inBraces = false, inRule = false;
-
-    var iter = {
-      next: function() {
-        var token = tokens.next(), style = token.style, content = token.content;
-
-        if (style == "css-identifier" && inRule)
-          token.style = "css-value";
-        if (style == "css-hash")
-          token.style =  inRule ? "css-colorcode" : "css-identifier";
-
-        if (content == "\n")
-          token.indentation = indentCSS(inBraces, inRule, basecolumn);
-
-        if (content == "{")
-          inBraces = true;
-        else if (content == "}")
-          inBraces = inRule = false;
-        else if (inBraces && content == ";")
-          inRule = false;
-        else if (inBraces && style != "css-comment" && style != "whitespace")
-          inRule = true;
-
-        return token;
-      },
-
-      copy: function() {
-        var _inBraces = inBraces, _inRule = inRule, _tokenState = tokens.state;
-        return function(source) {
-          tokens = tokenizeCSS(source, _tokenState);
-          inBraces = _inBraces;
-          inRule = _inRule;
-          return iter;
-        };
-      }
-    };
-    return iter;
-  }
-
-  return {make: parseCSS, electricChars: "}"};
-})();
diff --git a/typo3/sysext/t3editor/jslib/codemirror/parsehtmlmixed.js b/typo3/sysext/t3editor/jslib/codemirror/parsehtmlmixed.js
deleted file mode 100644 (file)
index 166967f..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-var HTMLMixedParser = Editor.Parser = (function() {
-  if (!(CSSParser && JSParser && XMLParser))
-    throw new Error("CSS, JS, and XML parsers must be loaded for HTML mixed mode to work.");
-  XMLParser.configure({useHTMLKludges: true});
-
-  function parseMixed(stream) {
-    var htmlParser = XMLParser.make(stream), localParser = null, inTag = false;
-    var iter = {next: top, copy: copy};
-
-    function top() {
-      var token = htmlParser.next();
-      if (token.content == "<")
-        inTag = true;
-      else if (token.style == "xml-tagname" && inTag === true)
-        inTag = token.content.toLowerCase();
-      else if (token.content == ">") {
-        if (inTag == "script")
-          iter.next = local(JSParser, "</script");
-        else if (inTag == "style")
-          iter.next = local(CSSParser, "</style");
-        inTag = false;
-      }
-      return token;
-    }
-    function local(parser, tag) {
-      var baseIndent = htmlParser.indentation();
-      localParser = parser.make(stream, baseIndent + 2);
-      return function() {
-        if (stream.lookAhead(tag, false, false, true)) {
-          localParser = null;
-          iter.next = top;
-          return top();
-        }
-
-        var token = localParser.next();
-        var lt = token.value.lastIndexOf("<"), sz = Math.min(token.value.length - lt, tag.length);
-        if (lt != -1 && token.value.slice(lt, lt + sz).toLowerCase() == tag.slice(0, sz) &&
-            stream.lookAhead(tag.slice(sz), false, false, true)) {
-          stream.push(token.value.slice(lt));
-          token.value = token.value.slice(0, lt);
-        }
-
-        if (token.indentation) {
-          var oldIndent = token.indentation;
-          token.indentation = function(chars) {
-            if (chars == "</")
-              return baseIndent;
-            else
-              return oldIndent(chars);
-          }
-        }
-
-        return token;
-      };
-    }
-
-    function copy() {
-      var _html = htmlParser.copy(), _local = localParser && localParser.copy(),
-          _next = iter.next, _inTag = inTag;
-      return function(_stream) {
-        stream = _stream;
-        htmlParser = _html(_stream);
-        localParser = _local && _local(_stream);
-        iter.next = _next;
-        inTag = _inTag;
-        return iter;
-      };
-    }
-    return iter;
-  }
-
-  return {make: parseMixed, electricChars: "{}/"};
-})();
diff --git a/typo3/sysext/t3editor/jslib/codemirror/parsejavascript.js b/typo3/sysext/t3editor/jslib/codemirror/parsejavascript.js
deleted file mode 100644 (file)
index 1b42cdc..0000000
+++ /dev/null
@@ -1,322 +0,0 @@
-/* Parse function for JavaScript. Makes use of the tokenizer from
- * tokenizejavascript.js. Note that your parsers do not have to be
- * this complicated -- if you don't want to recognize local variables,
- * in many languages it is enough to just look for braces, semicolons,
- * parentheses, etc, and know when you are inside a string or comment.
- *
- * See manual.html for more info about the parser interface.
- */
-
-var JSParser = Editor.Parser = (function() {
-  // Token types that can be considered to be atoms.
-  var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true};
-  // Constructor for the lexical context objects.
-  function JSLexical(indented, column, type, align, prev) {
-    // indentation at start of this line
-    this.indented = indented;
-    // column at which this scope was opened
-    this.column = column;
-    // type of scope ('vardef', 'stat' (statement), 'form' (special form), '[', '{', or '(')
-    this.type = type;
-    // '[', '{', or '(' blocks that have any text after their opening
-    // character are said to be 'aligned' -- any lines below are
-    // indented all the way to the opening character.
-    if (align != null)
-      this.align = align;
-    // Parent scope, if any.
-    this.prev = prev;
-  }
-  // My favourite JavaScript indentation rules.
-  function indentJS(lexical) {
-    return function(firstChars) {
-      var firstChar = firstChars && firstChars.charAt(0);
-      var closing = firstChar == lexical.type;
-      if (lexical.type == "vardef")
-        return lexical.indented + 4;
-      else if (lexical.type == "form" && firstChar == "{")
-        return lexical.indented;
-      else if (lexical.type == "stat" || lexical.type == "form")
-        return lexical.indented + 2;
-      else if (lexical.align)
-        return lexical.column - (closing ? 1 : 0);
-      else
-        return lexical.indented + (closing ? 0 : 2);
-    };
-  }
-
-  // The parser-iterator-producing function itself.
-  function parseJS(input, basecolumn) {
-    // Wrap the input in a token stream
-    var tokens = tokenizeJavaScript(input);
-    // The parser state. cc is a stack of actions that have to be
-    // performed to finish the current statement. For example we might
-    // know that we still need to find a closing parenthesis and a
-    // semicolon. Actions at the end of the stack go first. It is
-    // initialized with an infinitely looping action that consumes
-    // whole statements.
-    var cc = [statements];
-    // Context contains information about the current local scope, the
-    // variables defined in that, and the scopes above it.
-    var context = null;
-    // The lexical scope, used mostly for indentation.
-    var lexical = new JSLexical((basecolumn || 0) - 2, 0, "block", false);
-    // Current column, and the indentation at the start of the current
-    // line. Used to create lexical scope objects.
-    var column = 0;
-    var indented = 0;
-    // Variables which are used by the mark, cont, and pass functions
-    // below to communicate with the driver loop in the 'next'
-    // function.
-    var consume, marked;
-  
-    // The iterator object.
-    var parser = {next: next, copy: copy};
-
-    function next(){
-      // Start by performing any 'lexical' actions (adjusting the
-      // lexical variable), or the operations below will be working
-      // with the wrong lexical state.
-      while(cc[cc.length - 1].lex)
-        cc.pop()();
-
-      // Fetch a token.
-      var token = tokens.next();
-
-      // Adjust column and indented.
-      if (token.type == "whitespace" && column == 0)
-        indented = token.value.length;
-      column += token.value.length;
-      if (token.content == "\n"){
-        indented = column = 0;
-        // If the lexical scope's align property is still undefined at
-        // the end of the line, it is an un-aligned scope.
-        if (!("align" in lexical))
-          lexical.align = false;
-        // Newline tokens get an indentation function associated with
-        // them.
-        token.indentation = indentJS(lexical);
-      }
-      // No more processing for meaningless tokens.
-      if (token.type == "whitespace" || token.type == "comment")
-        return token;
-      // When a meaningful token is found and the lexical scope's
-      // align is undefined, it is an aligned scope.
-      if (!("align" in lexical))
-        lexical.align = true;
-
-      // Execute actions until one 'consumes' the token and we can
-      // return it.
-      while(true) {
-        consume = marked = false;
-        // Take and execute the topmost action.
-        cc.pop()(token.type, token.content);
-        if (consume){
-          // Marked is used to change the style of the current token.
-          if (marked)
-            token.style = marked;
-          // Here we differentiate between local and global variables.
-          else if (token.type == "variable" && inScope(token.content))
-            token.style = "js-localvariable";
-          return token;
-        }
-      }
-    }
-
-    // This makes a copy of the parser state. It stores all the
-    // stateful variables in a closure, and returns a function that
-    // will restore them when called with a new input stream. Note
-    // that the cc array has to be copied, because it is contantly
-    // being modified. Lexical objects are not mutated, and context
-    // objects are not mutated in a harmful way, so they can be shared
-    // between runs of the parser.
-    function copy(){
-      var _context = context, _lexical = lexical, _cc = cc.concat([]), _tokenState = tokens.state;
-  
-      return function copyParser(input){
-        context = _context;
-        lexical = _lexical;
-        cc = _cc.concat([]); // copies the array
-        column = indented = 0;
-        tokens = tokenizeJavaScript(input, _tokenState);
-        return parser;
-      };
-    }
-
-    // Helper function for pushing a number of actions onto the cc
-    // stack in reverse order.
-    function push(fs){
-      for (var i = fs.length - 1; i >= 0; i--)
-        cc.push(fs[i]);
-    }
-    // cont and pass are used by the action functions to add other
-    // actions to the stack. cont will cause the current token to be
-    // consumed, pass will leave it for the next action.
-    function cont(){
-      push(arguments);
-      consume = true;
-    }
-    function pass(){
-      push(arguments);
-      consume = false;
-    }
-    // Used to change the style of the current token.
-    function mark(style){
-      marked = style;
-    }
-
-    // Push a new scope. Will automatically link the current scope.
-    function pushcontext(){
-      context = {prev: context, vars: {"this": true, "arguments": true}};
-    }
-    // Pop off the current scope.
-    function popcontext(){
-      context = context.prev;
-    }
-    // Register a variable in the current scope.
-    function register(varname){
-      if (context){
-        mark("js-variabledef");
-        context.vars[varname] = true;
-      }
-    }
-    // Check whether a variable is defined in the current scope.
-    function inScope(varname){
-      var cursor = context;
-      while (cursor) {
-        if (cursor.vars[varname])
-          return true;
-        cursor = cursor.prev;
-      }
-      return false;
-    }
-  
-    // Push a new lexical context of the given type.
-    function pushlex(type){
-      var result = function(){
-        lexical = new JSLexical(indented, column, type, null, lexical)
-      };
-      result.lex = true;
-      return result;
-    }
-    // Pop off the current lexical context.
-    function poplex(){
-      lexical = lexical.prev;
-    }
-    poplex.lex = true;
-    // The 'lex' flag on these actions is used by the 'next' function
-    // to know they can (and have to) be ran before moving on to the
-    // next token.
-  
-    // Creates an action that discards tokens until it finds one of
-    // the given type.
-    function expect(wanted){
-      return function expecting(type){
-        if (type == wanted) cont();
-        else cont(arguments.callee);
-      };
-    }
-
-    // Looks for a statement, and then calls itself.
-    function statements(type){
-      return pass(statement, statements);
-    }
-    // Dispatches various types of statements based on the type of the
-    // current token.
-    function statement(type){
-      if (type == "var") cont(pushlex("vardef"), vardef1, expect(";"), poplex);
-      else if (type == "keyword a") cont(pushlex("form"), expression, statement, poplex);
-      else if (type == "keyword b") cont(pushlex("form"), statement, poplex);
-      else if (type == "{") cont(pushlex("}"), block, poplex);
-      else if (type == "function") cont(functiondef);
-      else if (type == "for") cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"), poplex, statement, poplex);
-      else if (type == "variable") cont(pushlex("stat"), maybelabel);
-      else if (type == "case") cont(expression, expect(":"));
-      else if (type == "default") cont(expect(":"));
-      else if (type == "catch") cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"), statement, poplex, popcontext);
-      else pass(pushlex("stat"), expression, expect(";"), poplex);
-    }
-    // Dispatch expression types.
-    function expression(type){
-      if (atomicTypes.hasOwnProperty(type)) cont(maybeoperator);
-      else if (type == "function") cont(functiondef);
-      else if (type == "keyword c") cont(expression);
-      else if (type == "(") cont(pushlex(")"), expression, expect(")"), poplex);
-      else if (type == "operator") cont(expression);
-      else if (type == "[") cont(pushlex("]"), commasep(expression), expect("]"), poplex);
-      else if (type == "{") cont(pushlex("}"), commasep(objprop), expect("}"), poplex);
-    }
-    // Called for places where operators, function calls, or
-    // subscripts are valid. Will skip on to the next action if none
-    // is found.
-    function maybeoperator(type){
-      if (type == "operator") cont(expression);
-      else if (type == "(") cont(pushlex(")"), expression, commasep(expression), expect(")"), poplex, maybeoperator);
-      else if (type == ".") cont(property, maybeoperator);
-      else if (type == "[") cont(pushlex("]"), expression, expect("]"), poplex, maybeoperator);
-    }
-    // When a statement starts with a variable name, it might be a
-    // label. If no colon follows, it's a regular statement.
-    function maybelabel(type){
-      if (type == ":") cont(poplex, statement);
-      else pass(maybeoperator, expect(";"), poplex);
-    }
-    // Property names need to have their style adjusted -- the
-    // tokenizer thinks they are variables.
-    function property(type){
-      if (type == "variable") {mark("js-property"); cont();}
-    }
-    // This parses a property and its value in an object literal.
-    function objprop(type){
-      if (type == "variable") mark("js-property");
-      if (atomicTypes.hasOwnProperty(type)) cont(expect(":"), expression);
-    }
-    // Parses a comma-separated list of the things that are recognized
-    // by the 'what' argument.
-    function commasep(what){
-      function proceed(type) {
-        if (type == ",") cont(what, proceed);
-      };
-      return function commaSeparated() {
-        pass(what, proceed);
-      };
-    }
-    // Look for statements until a closing brace is found.
-    function block(type){
-      if (type == "}") cont();
-      else pass(statement, block);
-    }
-    // Variable definitions are split into two actions -- 1 looks for
-    // a name or the end of the definition, 2 looks for an '=' sign or
-    // a comma.
-    function vardef1(type, value){
-      if (type == "variable"){register(value); cont(vardef2);}
-      else cont();
-    }
-    function vardef2(type){
-      if (type == "operator") cont(expression, vardef2);
-      else if (type == ",") cont(vardef1);
-    }
-    // For loops.
-    function forspec1(type, value){
-      if (type == "var") cont(vardef1, forspec2);
-      else cont(expression, forspec2);
-    }
-    function forspec2(type){
-      if (type == ",") cont(forspec1);
-      if (type == ";") cont(expression, expect(";"), expression);
-    }
-    // A function definition creates a new context, and the variables
-    // in its argument list have to be added to this context.
-    function functiondef(type, value){
-      if (type == "variable"){register(value); cont(functiondef);}
-      else if (type == "(") cont(pushcontext, commasep(funarg), expect(")"), statement, popcontext);
-    }
-    function funarg(type, value){
-      if (type == "variable"){register(value); cont();}
-    }
-  
-    return parser;
-  }
-
-  return {make: parseJS, electricChars: "{}"};
-})();
diff --git a/typo3/sysext/t3editor/jslib/codemirror/parsesparql.js b/typo3/sysext/t3editor/jslib/codemirror/parsesparql.js
deleted file mode 100644 (file)
index 6713d64..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-Editor.Parser = (function() {
-  function wordRegexp(words) {
-    return new RegExp("^(?:" + words.join("|") + ")$", "i");
-  }
-  var ops = wordRegexp(["str", "lang", "langmatches", "datatype", "bound", "sameterm", "isiri", "isuri",
-                        "isblank", "isliteral", "union", "a"]);
-  var keywords = wordRegexp(["base", "prefix", "select", "distinct", "reduced", "construct", "describe",
-                             "ask", "from", "named", "where", "order", "limit", "offset", "filter", "optional",
-                             "graph", "by", "asc", "desc", ]);
-  var operatorChars = /[*+\-<>=&|]/;
-
-  var tokenizeSparql = (function() {
-    function normal(source, setState) {
-      var ch = source.next();
-      if (ch == "$" || ch == "?") {
-        source.nextWhile(matcher(/[\w\d]/));
-        return "sp-var";
-      }
-      else if (ch == "<" && !source.applies(matcher(/[\s\u00a0=]/))) {
-        source.nextWhile(matcher(/[^\s\u00a0>]/));
-        if (source.equals(">")) source.next();
-        return "sp-uri";
-      }
-      else if (ch == "\"" || ch == "'") {
-        setState(inLiteral(ch));
-        return null;
-      }
-      else if (/[{}\(\),\.;\[\]]/.test(ch)) {
-        return "sp-punc";
-      }
-      else if (ch == "#") {
-        while (!source.endOfLine()) source.next();
-        return "sp-comment";
-      }
-      else if (operatorChars.test(ch)) {
-        source.nextWhile(matcher(operatorChars));
-        return "sp-operator";
-      }
-      else if (ch == ":") {
-        source.nextWhile(matcher(/[\w\d\._\-]/));
-        return "sp-prefixed";
-      }
-      else {
-        source.nextWhile(matcher(/[_\w\d]/));
-        if (source.equals(":")) {
-          source.next();
-          source.nextWhile(matcher(/[\w\d_\-]/));
-          return "sp-prefixed";
-        }
-        var word = source.get(), type;
-        if (ops.test(word))
-          type = "sp-operator";
-        else if (keywords.test(word))
-          type = "sp-keyword";
-        else
-          type = "sp-word";
-        return {style: type, content: word};
-      }
-    }
-
-    function inLiteral(quote) {
-      return function(source, setState) {
-        var escaped = false;
-        while (!source.endOfLine()) {
-          var ch = source.next();
-          if (ch == quote && !escaped) {
-            setState(normal);
-            break;
-          }
-          escaped = !escaped && ch == "\\";
-        }
-        return "sp-literal";
-      };
-    }
-
-    return function(source, startState) {
-      return tokenizer(source, startState || normal);
-    };
-  })();
-
-  function indentSparql(context) {
-    return function(nextChars) {
-      var firstChar = nextChars && nextChars.charAt(0);
-      if (/[\]\}]/.test(firstChar))
-        while (context && context.type == "pattern") context = context.prev;
-
-      var closing = context && firstChar == matching[context.type];
-      if (!context)
-        return 0;
-      else if (context.type == "pattern")
-        return context.col;
-      else if (context.align)
-        return context.col - (closing ? context.width : 0);
-      else
-        return context.indent + (closing ? 0 : 2);
-    }
-  }
-
-  function parseSparql(source) {
-    var tokens = tokenizeSparql(source);
-    var context = null, indent = 0, col = 0;
-    function pushContext(type, width) {
-      context = {prev: context, indent: indent, col: col, type: type, width: width};
-    }
-    function popContext() {
-      context = context.prev;
-    }
-
-    var iter = {
-      next: function() {
-        var token = tokens.next(), type = token.style, content = token.content, width = token.value.length;
-
-        if (content == "\n") {
-          token.indentation = indentSparql(context);
-          indent = col = 0;
-          if (context && context.align == null) context.align = false;
-        }
-        else if (type == "whitespace" && col == 0) {
-          indent = width;
-        }
-        else if (type != "sp-comment" && context && context.align == null) {
-          context.align = true;
-        }
-
-        if (content != "\n") col += width;
-
-        if (/[\[\{\(]/.test(content)) {
-          pushContext(content, width);
-        }
-        else if (/[\]\}\)]/.test(content)) {
-          while (context && context.type == "pattern")
-            popContext();
-          if (context && content == matching[context.type]) 
-            popContext();
-        }
-        else if (content == "." && context && context.type == "pattern") {
-          popContext();
-        }
-        else if ((type == "sp-word" || type == "sp-prefixed" || type == "sp-uri" || type == "sp-var" || type == "sp-literal") &&
-                 context && /[\{\[]/.test(context.type)) {
-          pushContext("pattern", width);
-        }
-
-        return token;
-      },
-
-      copy: function() {
-        var _context = context, _indent = indent, _col = col, _tokenState = tokens.state;
-        return function(source) {
-          tokens = tokenizeSparql(source, _tokenState);
-          context = _context;
-          indent = _indent;
-          col = _col;
-          return iter;
-        };
-      }
-    };
-    return iter;
-  }
-
-  return {make: parseSparql, electricChars: "}]"};
-})();
diff --git a/typo3/sysext/t3editor/jslib/codemirror/parsetyposcript.js b/typo3/sysext/t3editor/jslib/codemirror/parsetyposcript.js
deleted file mode 100644 (file)
index 80f9d4e..0000000
+++ /dev/null
@@ -1,457 +0,0 @@
-/* TypoScript parser
- *
- * based on parsejavascript.js by Marijn Haverbeke
- *
- * A parser that can be plugged into the CodeMirror system has to
- * implement the following interface: It is a function that, when
- * called with a string stream (stringstream.js) as an argument,
- * returns a MochiKit-style iterator (object with a 'next' method).
- * This iterator, when called, consumes some input from the string
- * stream, and returns a token object. Token objects must have a
- * 'value' property (the text they represent), a 'style' property (the
- * CSS style that should be used to colour them). Tokens for newline
- * characters must also have a 'lexicalContext' property, which has an
- * 'indentation' method that can be used to determine the proper
- * indentation level for the next line. This method optionally takes
- * the first character of the next line as an argument, which it can
- * use to adjust the indentation level.
- *
- * So far this should be easy. The hard part is that the iterator
- * produced by the parse function must also have a 'copy' method. This
- * method, called without arguments, returns a function representing
- * the current state of the parser. When this function is later called
- * with a string stream as its argument, it returns a parser iterator
- * object that resumes parsing using the old state and the new input
- * stream. It may assume that only one parser is active at a time, and
- * clobber the state of the old parser (the implementation below
- * certianly does).
- */
-
-// Parse function for TypoScript. Makes use of the tokenizer from
-// tokenizetyposcript.js. Note that your parsers do not have to be
-// this complicated -- if you don't want to recognize local variables,
-// in many languages it is enough to just look for braces, semicolons,
-// parentheses, etc, and know when you are inside a string or comment.
-Editor.Parser = (function() {
-       // Token types that can be considered to be atoms.
-       var atomicTypes = {
-               "atom": true,
-               "number": true,
-               "variable": true,
-               "string": true,
-               "regexp": true
-       };
-
-       // Constructor for the lexical context objects.
-       function TSLexical(indented, column, type, align, prev) {
-               // indentation at start of this line
-               this.indented = indented;
-               // column at which this scope was opened
-               this.column = column;
-               // type of scope ('vardef', 'stat' (statement), '[', '{', or '(')
-               this.type = type;
-               // '[', '{', or '(' blocks that have any text after their opening
-               // character are said to be 'aligned' -- any lines below are
-               // indented all the way to the opening character.
-               if (align != null) {
-                       this.align = align;
-               }
-               // Parent scope, if any.
-               this.prev = prev;
-
-       }
-       
-       
-       // My favourite TypoScript indentation rules.
-       function indentTS(lexical) {
-               return function(firstChars) {
-                       var firstChar = firstChars && firstChars.charAt(0);
-                       var closing = firstChar == lexical.type;
-
-                       if (lexical.type == "{" && firstChar != "}") {
-                               return lexical.indented + 2;
-                       }
-
-                       if (firstChar == "}" && lexical.prev) {
-                               lexical = lexical.prev;
-                       }
-                       
-                       if (lexical.align) {
-                               return lexical.column - (closing ? 1: 0);
-                       } else {
-                               return lexical.indented + (closing ? 0: 2);
-                       }
-
-               };
-       }
-
-       // The parser-iterator-producing function itself.
-       function parseTS(input) {
-               // Wrap the input in a token stream
-               var tokens = tokenizeTypoScript(input);
-               // The parser state. cc is a stack of actions that have to be
-               // performed to finish the current statement. For example we might
-               // know that we still need to find a closing parenthesis and a
-               // semicolon. Actions at the end of the stack go first. It is
-               // initialized with an infinitely looping action that consumes
-               // whole statements.
-               var cc = [statements];
-               // Context contains information about the current local scope, the
-               // variables defined in that, and the scopes above it.
-               var context = null;
-               // The lexical scope, used mostly for indentation.
-               var lexical = new TSLexical( -2, 0, "block", false);
-               // Current column, and the indentation at the start of the current
-               // line. Used to create lexical scope objects.
-               var column = 0;
-               var indented = 0;
-               // Variables which are used by the mark, cont, and pass functions
-               // below to communicate with the driver loop in the 'next'
-               // function.
-               var consume,
-               marked;
-
-               // The iterator object.
-               var parser = {
-                       next: next,
-                       copy: copy
-               };
-
-               function next() {
-                       // Start by performing any 'lexical' actions (adjusting the
-                       // lexical variable), or the operations below will be working
-                       // with the wrong lexical state.
-                       while (cc[cc.length - 1].lex) {
-                               cc.pop()();
-                       }
-
-                       // Fetch a token.
-                       var token = tokens.next();
-                       // Adjust column and indented.
-                       if (token.type == "whitespace" && column == 0) {
-                               indented = token.value.length;
-                       }
-                       column += token.value.length;
-                       if (token.type == "newline") {
-                               indented = column = 0;
-                               // If the lexical scope's align property is still undefined at
-                               // the end of the line, it is an un-aligned scope.
-                               if (! ("align" in lexical)) {
-                                       lexical.align = false;
-                               }
-                       // Newline tokens get a lexical context associated with them,
-                               // which is used for indentation.
-                               token.indentation = indentTS(lexical);
-                       }
-                       // No more processing for meaningless tokens.
-                       if (token.type == "whitespace" || token.type == "newline" || token.type == "comment") {
-                               return token;
-                       }
-                       // When a meaningful token is found and the lexical scope's
-                       // align is undefined, it is an aligned scope.
-                       if (! ("align" in lexical)) {
-                               lexical.align = true;
-                       }
-                       // Execute actions until one 'consumes' the token and we can
-                       // return it. Marked is used to
-                       while (true) {
-                               consume = marked = false;
-                               // Take and execute the topmost action.
-                               cc.pop()(token.type, token.name);
-                               if (consume) {
-                                       // Marked is used to change the style of the current token.
-                                       if (marked) {
-                                               token.style = marked;
-                                       }
-                                       return token;
-                               }
-                       }
-               }
-
-               // This makes a copy of the parser state. It stores all the
-               // stateful variables in a closure, and returns a function that
-               // will restore them when called with a new input stream. Note
-               // that the cc array has to be copied, because it is contantly
-               // being modified. Lexical objects are not mutated, and context
-               // objects are not mutated in a harmful way, so they can be shared
-               // between runs of the parser.
-               function copy() {
-                       var _context = context,
-                       _lexical = lexical,
-                       _cc = cc.concat([]),
-                       _regexp = tokens.regexp,
-                       _comment = tokens.inComment;
-
-                       return function(input) {
-                               context = _context;
-                               lexical = _lexical;
-                               cc = _cc.concat([]);
-                               // copies the array
-                               column = indented = 0;
-                               tokens = tokenizeTypoScript(input);
-                               tokens.regexp = _regexp;
-                               tokens.inComment = _comment;
-                               return parser;
-                       };
-               }
-
-               // Helper function for pushing a number of actions onto the cc
-               // stack in reverse order.
-               function push(fs) {
-                       for (var i = fs.length - 1; i >= 0; i--) {
-                               cc.push(fs[i]);
-                       }
-               }
-
-               // cont and pass are used by the action functions to add other
-               // actions to the stack. cont will cause the current token to be
-               // consumed, pass will leave it for the next action.
-               function cont() {
-                       push(arguments);
-                       consume = true;
-               }
-
-               function pass() {
-                       push(arguments);
-                       consume = false;
-               }
-
-               // Used to change the style of the current token.
-               function mark(style) {
-                       marked = style;
-               }
-
-               // Push a new scope. Will automatically link the the current
-               // scope.
-               function pushcontext() {
-                       context = {
-                               prev: context,
-                               vars: {
-                                       "this": true,
-                                       "arguments": true
-                               }
-                       };
-               }
-
-               // Pop off the current scope.
-               function popcontext() {
-                       context = context.prev;
-               }
-
-               // Register a variable in the current scope.
-               function register(varname) {
-                       if (context) {
-                               mark("variabledef");
-                               context.vars[varname] = true;
-                       }
-               }
-
-               // Push a new lexical context of the given type.
-               function pushlex(type) {
-                       var result = function() {
-                               lexical = new TSLexical(indented, column, type, null, lexical)
-                       };
-                       result.lex = true;
-                       return result;
-               }
-
-               // Pop off the current lexical context.
-               function poplex() {
-                       lexical = lexical.prev;
-               }
-
-               poplex.lex = true;
-               // The 'lex' flag on these actions is used by the 'next' function
-               // to know they can (and have to) be ran before moving on to the
-               // next token.
-
-               // Creates an action that discards tokens until it finds one of
-               // the given type.
-               function expect(wanted) {
-                       return function(type) {
-                               if (type == wanted) {
-                                       cont();
-                               } else {
-                                       cont(arguments.callee);
-                               }
-                       };
-               }
-
-               // Looks for a statement, and then calls itself.
-               function statements(type) {
-                       return pass(statement, statements);
-               }
-               // Dispatches various types of statements based on the type of the
-               // current token.
-               function statement(type) {
-                       if (type == "{") {
-                               cont(pushlex("{"), block, poplex);
-                       } else {
-                               cont();
-                       }
-               }
-
-               // Dispatch expression types.
-               function expression(type) {
-                       if (atomicTypes.hasOwnProperty(type)) {
-                               cont(maybeoperator);
-
-                       } else if (type == "function") {
-                               cont(functiondef);
-
-                       } else if (type == "keyword c") {
-                               cont(expression);
-
-                       } else if (type == "(") {
-                               cont(pushlex(")"), expression, expect(")"), poplex);
-
-                       } else if (type == "operator") {
-                               cont(expression);
-
-                       } else if (type == "[") {
-                               cont(pushlex("]"), commasep(expression), expect("]"), poplex);
-
-                       } else if (type == "{") {
-                               cont(pushlex("}"), commasep(objprop), expect("}"), poplex);
-                       }
-               }
-
-               // Called for places where operators, function calls, or
-               // subscripts are valid. Will skip on to the next action if none
-               // is found.
-               function maybeoperator(type) {
-                       if (type == "operator") {
-                               cont(expression);
-
-                       } else if (type == "(") {
-                               cont(pushlex(")"), expression, commasep(expression), expect(")"), poplex);
-
-                       } else if (type == ".") {
-                               cont(property, maybeoperator);
-
-                       } else if (type == "[") {
-                               cont(pushlex("]"), expression, expect("]"), poplex);
-                       }
-               }
-
-               // When a statement starts with a variable name, it might be a
-               // label. If no colon follows, it's a regular statement.
-               function maybelabel(type) {
-                       if (type == ":") {
-                               cont(poplex, statement);
-                       } else {
-                               pass(maybeoperator, expect(";"), poplex);
-                       }
-               }
-
-               // Property names need to have their style adjusted -- the
-               // tokenizer think they are variables.
-               function property(type) {
-                       if (type == "variable") {
-                               mark("property");
-                               cont();
-                       }
-               }
-
-               // This parses a property and its value in an object literal.
-               function objprop(type) {
-                       if (type == "variable") {
-                               mark("property");
-                       }
-                       if (atomicTypes.hasOwnProperty(type)) {
-                               cont(expect(":"), expression);
-                       }
-               }
-
-               // Parses a comma-separated list of the things that are recognized
-               // by the 'what' argument.
-               function commasep(what) {
-                       function proceed(type) {
-                               if (type == ",") {
-                                       cont(what, proceed);
-                               }
-                       };
-                       return function() {
-                               pass(what, proceed);
-                       };
-               }
-
-               // Look for statements until a closing brace is found.
-               function block(type) {
-                       if (type == "}") {
-                               cont();
-                       } else {
-                               pass(statement, block);
-                       }
-               }
-
-               // Look for statements until a closing brace is found.
-               function condition(type) {
-                       if (type == "]") {
-                               cont();
-                       } else {
-                               pass(statement, block);
-                       }
-               }
-
-               // Variable definitions are split into two actions -- 1 looks for
-               // a name or the end of the definition, 2 looks for an '=' sign or
-               // a comma.
-               function vardef1(type, value) {
-                       if (type == "variable") {
-                               register(value);
-                               cont(vardef2);
-                       } else {
-                               cont();
-                       }
-               }
-
-               function vardef2(type) {
-                       if (type == "operator") {
-                               cont(expression, vardef2);
-                       } else if (type == ",") {
-                               cont(vardef1);
-                       }
-               }
-
-               // For loops.
-               function forspec1(type, value) {
-                       if (type == "var") {
-                               cont(vardef1, forspec2);
-                       } else {
-                               cont(expression, forspec2);
-                       }
-               }
-
-               function forspec2(type) {
-                       if (type == ",") {
-                               cont(forspec1);
-                       }
-                       if (type == ";") {
-                               cont(expression, expect(";"), expression);
-                       }
-               }
-
-               // A function definition creates a new context, and the variables
-               // in its argument list have to be added to this context.
-               function functiondef(type, value) {
-                       if (type == "variable") {
-                               register(value);
-                               cont(functiondef);
-                       } else if (type == "(") {
-                               cont(pushcontext, commasep(funarg), expect(")"), statement, popcontext);
-                       }
-               }
-
-               function funarg(type, value) {
-                       if (type == "variable") {
-                               register(value);
-                               cont();
-                       }
-               }
-
-               return parser;
-       }
-       
-       return {make: parseTS, electricChars: "{}"};
-})();
\ No newline at end of file
diff --git a/typo3/sysext/t3editor/jslib/codemirror/parsexml.js b/typo3/sysext/t3editor/jslib/codemirror/parsexml.js
deleted file mode 100644 (file)
index 1f96d85..0000000
+++ /dev/null
@@ -1,286 +0,0 @@
-/* This file defines an XML parser, with a few kludges to make it
- * useable for HTML. autoSelfClosers defines a set of tag names that
- * are expected to not have a closing tag, and doNotIndent specifies
- * the tags inside of which no indentation should happen (see Config
- * object). These can be disabled by passing the editor an object like
- * {useHTMLKludges: false} as parserConfig option.
- */
-
-var XMLParser = Editor.Parser = (function() {
-  var Kludges = {
-    autoSelfClosers: {"br": true, "img": true, "hr": true, "link": true, "input": true,
-                      "meta": true, "col": true, "frame": true, "base": true, "area": true},
-    doNotIndent: {"pre": true}
-  };
-  var NoKludges = {autoSelfClosers: {}, doNotIndent: {}};
-  var UseKludges = Kludges;
-
-  // Simple stateful tokenizer for XML documents. Returns a
-  // MochiKit-style iterator, with a state property that contains a
-  // function encapsulating the current state. See tokenize.js.
-  var tokenizeXML = (function() {
-    function inText(source, setState) {
-      var ch = source.next();
-      if (ch == "<") {
-        if (source.equals("!")) {
-          source.next();
-          if (source.equals("[")) {
-            if (source.lookAhead("[CDATA[", true)) {
-              setState(inBlock("xml-cdata", "]]>"));
-              return null;
-            }
-            else {
-              return "xml-text";
-            }
-          }
-          else if (source.lookAhead("--", true)) {
-            setState(inBlock("xml-comment", "-->"));
-            return null;
-          }
-          else {
-            return "xml-text";
-          }
-        }
-        else if (source.equals("?")) {
-          source.next();
-          source.nextWhile(matcher(/[\w\._\-]/));
-          setState(inBlock("xml-processing", "?>"));
-          return "xml-processing";
-        }
-        else {
-          if (source.equals("/")) source.next();
-          setState(inTag);
-          return "xml-punctuation";
-        }
-      }
-      else if (ch == "&") {
-        while (!source.endOfLine()) {
-          if (source.next() == ";")
-            break;
-        }
-        return "xml-entity";
-      }
-      else {
-        source.nextWhile(matcher(/[^&<\n]/));
-        return "xml-text";
-      }
-    }
-
-    function inTag(source, setState) {
-      var ch = source.next();
-      if (ch == ">") {
-        setState(inText);
-        return "xml-punctuation";
-      }
-      else if (/[?\/]/.test(ch) && source.equals(">")) {
-        source.next();
-        setState(inText);
-        return "xml-punctuation";
-      }
-      else if (ch == "=") {
-        return "xml-punctuation";
-      }
-      else if (/[\'\"]/.test(ch)) {
-        setState(inAttribute(ch));
-        return null;
-      }
-      else {
-        source.nextWhile(matcher(/[^\s\u00a0=<>\"\'\/?]/));
-        return "xml-name";
-      }
-    }
-
-    function inAttribute(quote) {
-      return function(source, setState) {
-        while (!source.endOfLine()) {
-          if (source.next() == quote) {
-            setState(inTag);
-            break;
-          }
-        }
-        return "xml-attribute";
-      };
-    }
-
-    function inBlock(style, terminator) {
-      return function(source, setState) {
-        while (!source.endOfLine()) {
-          if (source.lookAhead(terminator, true)) {
-            setState(inText);
-            break;
-          }
-          source.next();
-        }
-        return style;
-      };
-    }
-
-    return function(source, startState) {
-      return tokenizer(source, startState || inText);
-    };
-  })();
-
-  // The parser. The structure of this function largely follows that of
-  // parseJavaScript in parsejavascript.js (there is actually a bit more
-  // shared code than I'd like), but it is quite a bit simpler.
-  function parseXML(source) {
-    var tokens = tokenizeXML(source);
-    var cc = [base];
-    var tokenNr = 0, indented = 0;
-    var currentTag = null, context = null;
-    var consume, marked;
-    
-    function push(fs) {
-      for (var i = fs.length - 1; i >= 0; i--)
-        cc.push(fs[i]);
-    }
-    function cont() {
-      push(arguments);
-      consume = true;
-    }
-    function pass() {
-      push(arguments);
-      consume = false;
-    }
-
-    function mark(style) {
-      marked = style;
-    }
-    function expect(text) {
-      return function(style, content) {
-        if (content == text) cont();
-        else mark("xml-error") || cont(arguments.callee);
-      };
-    }
-
-    function pushContext(tagname, startOfLine) {
-      var noIndent = UseKludges.doNotIndent.hasOwnProperty(tagname) || (context && context.noIndent);
-      context = {prev: context, name: tagname, indent: indented, startOfLine: startOfLine, noIndent: noIndent};
-    }
-    function popContext() {
-      context = context.prev;
-    }
-    function computeIndentation(baseContext) {
-      return function(nextChars) {
-        var context = baseContext;
-        if (context && context.noIndent)
-          return 0;
-        if (context && /^<\//.test(nextChars))
-          context = context.prev;
-        while (context && !context.startOfLine)
-          context = context.prev;
-        if (context)
-          return context.indent + 2;
-        else
-          return 0;
-      };
-    }
-
-    function base() {
-      return pass(element, base);
-    }
-    var harmlessTokens = {"xml-text": true, "xml-entity": true, "xml-comment": true,
-                          "xml-cdata": true, "xml-processing": true};
-    function element(style, content) {
-      if (content == "<") cont(tagname, attributes, endtag(tokenNr == 1));
-      else if (content == "</") cont(closetagname, expect(">"));
-      else if (content == "<?") cont(tagname, attributes, expect("?>"));
-      else if (harmlessTokens.hasOwnProperty(style)) cont();
-      else mark("xml-error") || cont();
-    }
-    function tagname(style, content) {
-      if (style == "xml-name") {
-        currentTag = content.toLowerCase();
-        mark("xml-tagname");
-        cont();
-      }
-      else {
-        currentTag = null;
-        pass();
-      }
-    }
-    function closetagname(style, content) {
-      if (style == "xml-name" && context && content.toLowerCase() == context.name) {
-        popContext();
-        mark("xml-tagname");
-      }
-      else {
-        mark("xml-error");
-      }
-      cont();
-    }
-    function endtag(startOfLine) {
-      return function(style, content) {
-        if (content == "/>" || (content == ">" && UseKludges.autoSelfClosers.hasOwnProperty(currentTag))) cont();
-        else if (content == ">") pushContext(currentTag, startOfLine) || cont();
-        else mark("xml-error") || cont(arguments.callee);
-      };
-    }
-    function attributes(style) {
-      if (style == "xml-name") mark("xml-attname") || cont(attribute, attributes);
-      else pass();
-    }
-    function attribute(style, content) {
-      if (content == "=") cont(value);
-      else if (content == ">" || content == "/>") pass(endtag);
-      else pass();
-    }
-    function value(style) {
-      if (style == "xml-attribute") cont(value);
-      else pass();
-    }
-
-    return {
-      indentation: function() {return indented;},
-
-      next: function(){
-        var token = tokens.next();
-        if (token.style == "whitespace" && tokenNr == 0)
-          indented = token.value.length;
-        else
-          tokenNr++;
-        if (token.content == "\n") {
-          indented = tokenNr = 0;
-          token.indentation = computeIndentation(context);
-        }
-
-        if (token.style == "whitespace" || token.type == "xml-comment")
-          return token;
-
-        while(true){
-          consume = marked = false;
-          cc.pop()(token.style, token.content);
-          if (consume){
-            if (marked)
-              token.style = marked;
-            return token;
-          }
-        }
-      },
-
-      copy: function(){
-        var _cc = cc.concat([]), _tokenState = tokens.state, _context = context;
-        var parser = this;
-        
-        return function(input){
-          cc = _cc.concat([]);
-          tokenNr = indented = 0;
-          context = _context;
-          tokens = tokenizeXML(input, _tokenState);
-          return parser;
-        };
-      }
-    };
-  }
-
-  return {
-    make: parseXML,
-    electricChars: "/",
-    configure: function(config) {
-      if (config.useHTMLKludges)
-        UseKludges = Kludges;
-      else
-        UseKludges = NoKludges;
-    }
-  };
-})();
diff --git a/typo3/sysext/t3editor/jslib/codemirror/select.js b/typo3/sysext/t3editor/jslib/codemirror/select.js
deleted file mode 100644 (file)
index 5fb32eb..0000000
+++ /dev/null
@@ -1,607 +0,0 @@
-/* Functionality for finding, storing, and restoring selections
- *
- * This does not provide a generic API, just the minimal functionality
- * required by the CodeMirror system.
- */
-
-// Namespace object.
-var select = {};
-
-(function() {
-  select.ie_selection = document.selection && document.selection.createRangeCollection;
-
-  // Find the 'top-level' (defined as 'a direct child of the node
-  // passed as the top argument') node that the given node is
-  // contained in. Return null if the given node is not inside the top
-  // node.
-  function topLevelNodeAt(node, top) {
-    while (node && node.parentNode != top)
-      node = node.parentNode;
-    return node;
-  }
-
-  // Find the top-level node that contains the node before this one.
-  function topLevelNodeBefore(node, top) {
-    while (!node.previousSibling && node.parentNode != top)
-      node = node.parentNode;
-    return topLevelNodeAt(node.previousSibling, top);
-  }
-
-  // Used to prevent restoring a selection when we do not need to.
-  var currentSelection = null;
-
-  var fourSpaces = "\u00a0\u00a0\u00a0\u00a0";
-
-  select.snapshotChanged = function() {
-    if (currentSelection) currentSelection.changed = true;
-  };
-
-  // This is called by the code in editor.js whenever it is replacing
-  // a text node. The function sees whether the given oldNode is part
-  // of the current selection, and updates this selection if it is.
-  // Because nodes are often only partially replaced, the length of
-  // the part that gets replaced has to be taken into account -- the
-  // selection might stay in the oldNode if the newNode is smaller
-  // than the selection's offset. The offset argument is needed in
-  // case the selection does move to the new object, and the given
-  // length is not the whole length of the new node (part of it might
-  // have been used to replace another node).
-  select.snapshotReplaceNode = function(from, to, length, offset) {
-    if (!currentSelection) return;
-    currentSelection.changed = true;
-
-    function replace(point) {
-      if (from == point.node) {
-        if (length && point.offset > length) {
-          point.offset -= length;
-        }
-        else {
-          point.node = to;
-          point.offset += (offset || 0);
-        }
-      }
-    }
-    replace(currentSelection.start);
-    replace(currentSelection.end);
-  };
-
-  select.snapshotMove = function(from, to, distance, relative, ifAtStart) {
-    if (!currentSelection) return;
-    currentSelection.changed = true;
-
-    function move(point) {
-      if (from == point.node && (!ifAtStart || point.offset == 0)) {
-        point.node = to;
-        if (relative) point.offset = Math.max(0, point.offset + distance);
-        else point.offset = distance;
-      }
-    }
-    move(currentSelection.start);
-    move(currentSelection.end);
-  };
-
-  // Most functions are defined in two ways, one for the IE selection
-  // model, one for the W3C one.
-  if (select.ie_selection) {
-    function selectionNode(win, start) {
-      var range = win.document.selection.createRange();
-      range.collapse(start);
-
-      function nodeAfter(node) {
-        var found = null;
-        while (!found && node) {
-          found = node.nextSibling;
-          node = node.parentNode;
-        }
-        return nodeAtStartOf(found);
-      }
-
-      function nodeAtStartOf(node) {
-        while (node && node.firstChild) node = node.firstChild;
-        return {node: node, offset: 0};
-      }
-
-      var containing = range.parentElement();
-      if (!isAncestor(win.document.body, containing)) return null;
-      if (!containing.firstChild) return nodeAtStartOf(containing);
-
-      var working = range.duplicate();
-      working.moveToElementText(containing);
-      working.collapse(true);
-      for (var cur = containing.firstChild; cur; cur = cur.nextSibling) {
-        if (cur.nodeType == 3) {
-          var size = cur.nodeValue.length;
-          working.move("character", size);
-        }
-        else {
-          working.moveToElementText(cur);
-          working.collapse(false);
-        }
-
-        var dir = range.compareEndPoints("StartToStart", working);
-        if (dir == 0) return nodeAfter(cur);
-        if (dir == 1) continue;
-        if (cur.nodeType != 3) return nodeAtStartOf(cur);
-
-        working.setEndPoint("StartToEnd", range);
-        return {node: cur, offset: size - working.text.length};
-      }
-      return nodeAfter(containing);
-    }
-
-    select.markSelection = function(win) {
-      currentSelection = null;
-      var sel = win.document.selection;
-      if (!sel) return;
-      var start = selectionNode(win, true),
-          end = sel.createRange().text == "" ? start : selectionNode(win, false);
-      if (!start || !end) return;
-      currentSelection = {start: start, end: end, window: win, changed: false};
-    };
-
-    select.selectMarked = function() {
-      if (!currentSelection || !currentSelection.changed) return;
-
-      function makeRange(point) {
-        var range = currentSelection.window.document.body.createTextRange();
-        var node = point.node;
-        if (!node) {
-          range.moveToElementText(win.document.body);
-          range.collapse(false);
-        }
-        else if (node.nodeType == 3) {
-          range.moveToElementText(node.parentNode);
-          var offset = point.offset;
-          while (node.previousSibling) {
-            node = node.previousSibling;
-            offset += (node.innerText || "").length;
-          }
-          range.move("character", offset);
-        }
-        else {
-          range.moveToElementText(node);
-          range.collapse(true);
-        }
-        return range;
-      }
-
-      var start = makeRange(currentSelection.start), end = makeRange(currentSelection.end);
-      start.setEndPoint("StartToEnd", end);
-      start.select();
-    };
-
-    // Get the top-level node that one end of the cursor is inside or
-    // after. Note that this returns false for 'no cursor', and null
-    // for 'start of document'.
-    select.selectionTopNode = function(container, start) {
-      var selection = container.ownerDocument.selection;
-      if (!selection) return false;
-
-      var range = selection.createRange();
-      range.collapse(start);
-      var around = range.parentElement();
-      if (around && isAncestor(container, around)) {
-        // Only use this node if the selection is not at its start.
-        var range2 = range.duplicate();
-        range2.moveToElementText(around);
-        if (range.compareEndPoints("StartToStart", range2) == -1)
-          return topLevelNodeAt(around, container);
-      }
-      // Fall-back hack
-      try {range.pasteHTML("<span id='xxx-temp-xxx'></span>");}
-      catch (e) {return false;}
-
-      var temp = container.ownerDocument.getElementById("xxx-temp-xxx");
-      if (temp) {
-        var result = topLevelNodeBefore(temp, container);
-        removeElement(temp);
-        return result;
-      }
-      return false;
-    };
-
-    // Place the cursor after this.start. This is only useful when
-    // manually moving the cursor instead of restoring it to its old
-    // position.
-    select.focusAfterNode = function(node, container) {
-      var range = container.ownerDocument.body.createTextRange();
-      range.moveToElementText(node || container);
-      range.collapse(!node);
-      range.select();
-    };
-
-    select.somethingSelected = function(win) {
-      var sel = win.document.selection;
-      return sel && (sel.createRange().text != "");
-    };
-
-    function insertAtCursor(window, html) {
-      var selection = window.document.selection;
-      if (selection) {
-        var range = selection.createRange();
-        range.pasteHTML(html);
-        range.collapse(false);
-        range.select();
-      }
-    }
-
-    // Insert a custom string at current cursor position (added for t3editor)
-    select.insertTextAtCursor = function(window, text) {
-            var selection = window.document.selection;
-            if (selection) {
-                    var range = selection.createRange();
-                    range.pasteHTML(text);
-                    range.collapse(false);
-                    range.select();
-            }
-     };
-
-
-    // Used to normalize the effect of the enter key, since browsers
-    // do widely different things when pressing enter in designMode.
-    select.insertNewlineAtCursor = function(window) {
-      insertAtCursor(window, "<br/>");
-    };
-
-    select.insertTabAtCursor = function(window) {
-      insertAtCursor(window, fourSpaces);
-    };
-
-    // Get the BR node at the start of the line on which the cursor
-    // currently is, and the offset into the line. Returns null as
-    // node if cursor is on first line.
-    select.cursorPos = function(container, start) {
-      var selection = container.ownerDocument.selection;
-      if (!selection) return null;
-
-      var topNode = select.selectionTopNode(container, start);
-      while (topNode && topNode.nodeName != "BR")
-        topNode = topNode.previousSibling;
-
-      var range = selection.createRange(), range2 = range.duplicate();
-      range.collapse(start);
-      if (topNode) {
-        range2.moveToElementText(topNode);
-        range2.collapse(false);
-      }
-      else {
-        // When nothing is selected, we can get all kinds of funky errors here.
-        try { range2.moveToElementText(container); }
-        catch (e) { return null; }
-        range2.collapse(true);
-      }
-      range.setEndPoint("StartToStart", range2);
-
-      return {node: topNode, offset: range.text.length};
-    };
-
-    select.setCursorPos = function(container, from, to) {
-      function rangeAt(pos) {
-        var range = container.ownerDocument.body.createTextRange();
-        if (!pos.node) {
-          range.moveToElementText(container);
-          range.collapse(true);
-        }
-        else {
-          range.moveToElementText(pos.node);
-          range.collapse(false);
-        }
-        range.move("character", pos.offset);
-        return range;
-      }
-
-      var range = rangeAt(from);
-      if (to && to != from)
-        range.setEndPoint("EndToEnd", rangeAt(to));
-      range.select();
-    }
-
-    // Make sure the cursor is visible.
-    select.scrollToCursor = function(container) {
-      var selection = container.ownerDocument.selection;
-      if (!selection) return null;
-      selection.createRange().scrollIntoView();
-    };
-
-    // Some hacks for storing and re-storing the selection when the editor loses and regains focus.
-    select.selectionCoords = function (win) {
-      var selection = win.document.selection;
-      if (!selection) return null;
-      var start = selection.createRange(), end = start.duplicate();
-      start.collapse(true);
-      end.collapse(false);
-
-      var body = win.document.body;
-      return {start: {x: start.boundingLeft + body.scrollLeft - 1,
-                      y: start.boundingTop + body.scrollTop},
-              end: {x: end.boundingLeft + body.scrollLeft - 1,
-                    y: end.boundingTop + body.scrollTop}};
-    };
-
-    // Restore a stored selection.
-    select.selectCoords = function(win, coords) {
-      if (!coords) return;
-
-      var range1 = win.document.body.createTextRange(), range2 = range1.duplicate();
-      // This can fail for various hard-to-handle reasons.
-      try {
-        range1.moveToPoint(coords.start.x, coords.start.y);
-        range2.moveToPoint(coords.end.x, coords.end.y);
-        range1.setEndPoint("EndToStart", range2);
-        range1.select();
-      } catch(e) {alert(e.message);}
-    };
-  }
-  // W3C model
-  else {
-    // This is used to fix an issue with getting the scroll position
-    // in Opera.
-    var opera_scroll = window.scrollX == null;
-
-    // Store start and end nodes, and offsets within these, and refer
-    // back to the selection object from those nodes, so that this
-    // object can be updated when the nodes are replaced before the
-    // selection is restored.
-    select.markSelection = function (win) {
-      var selection = win.getSelection();
-      if (!selection || selection.rangeCount == 0)
-        return (currentSelection = null);
-      var range = selection.getRangeAt(0);
-
-      currentSelection = {
-        start: {node: range.startContainer, offset: range.startOffset},
-        end: {node: range.endContainer, offset: range.endOffset},
-        window: win,
-        scrollX: opera_scroll && win.document.body.scrollLeft,
-        scrollY: opera_scroll && win.document.body.scrollTop,
-        changed: false
-      };
-
-      // We want the nodes right at the cursor, not one of their
-      // ancestors with a suitable offset. This goes down the DOM tree
-      // until a 'leaf' is reached (or is it *up* the DOM tree?).
-      function normalize(point){
-        while (point.node.nodeType != 3 && point.node.nodeName != "BR") {
-          var newNode = point.node.childNodes[point.offset] || point.node.nextSibling;
-          point.offset = 0;
-          while (!newNode && point.node.parentNode) {
-            point.node = point.node.parentNode;
-            newNode = point.node.nextSibling;
-          }
-          point.node = newNode;
-          if (!newNode)
-            break;
-        }
-      }
-
-      normalize(currentSelection.start);
-      normalize(currentSelection.end);
-    };
-
-    select.selectMarked = function () {
-      if (!currentSelection || !currentSelection.changed) return;
-      var win = currentSelection.window, range = win.document.createRange();
-
-      function setPoint(point, which) {
-        if (point.node) {
-          // Some magic to generalize the setting of the start and end
-          // of a range.
-          if (point.offset == 0)
-            range["set" + which + "Before"](point.node);
-          else
-            range["set" + which](point.node, point.offset);
-        }
-        else {
-          range.setStartAfter(win.document.body.lastChild || win.document.body);
-        }
-      }
-
-      // Have to restore the scroll position of the frame in Opera.
-      if (opera_scroll) {
-        win.document.body.scrollLeft = currentSelection.scrollX;
-        win.document.body.scrollTop = currentSelection.scrollY;
-      }
-      setPoint(currentSelection.end, "End");
-      setPoint(currentSelection.start, "Start");
-      selectRange(range, win);
-    };
-
-    // Helper for selecting a range object.
-    function selectRange(range, window) {
-      var selection = window.getSelection();
-      selection.removeAllRanges();
-      selection.addRange(range);
-    };
-    function selectionRange(window) {
-      var selection = window.getSelection();
-      if (!selection || selection.rangeCount == 0)
-        return false;
-      else
-        return selection.getRangeAt(0);
-    }
-
-    // Finding the top-level node at the cursor in the W3C is, as you
-    // can see, quite an involved process.
-    select.selectionTopNode = function(container, start) {
-      var range = selectionRange(container.ownerDocument.defaultView);
-      if (!range) return false;
-
-      var node = start ? range.startContainer : range.endContainer;
-      var offset = start ? range.startOffset : range.endOffset;
-      // Work around (yet another) bug in Opera's selection model.
-      if (window.opera && !start && range.endContainer == container && range.endOffset == range.startOffset + 1 &&
-          container.childNodes[range.startOffset] && container.childNodes[range.startOffset].nodeName == "BR")
-        offset--;
-
-      // For text nodes, we look at the node itself if the cursor is
-      // inside, or at the node before it if the cursor is at the
-      // start.
-      if (node.nodeType == 3){
-        if (offset > 0)
-          return topLevelNodeAt(node, container);
-        else
-          return topLevelNodeBefore(node, container);
-      }
-      // Occasionally, browsers will return the HTML node as
-      // selection. If the offset is 0, we take the start of the frame
-      // ('after null'), otherwise, we take the last node.
-      else if (node.nodeName == "HTML") {
-        return (offset == 1 ? null : container.lastChild);
-      }
-      // If the given node is our 'container', we just look up the
-      // correct node by using the offset.
-      else if (node == container) {
-        return (offset == 0) ? null : node.childNodes[offset - 1];
-      }
-      // In any other case, we have a regular node. If the cursor is
-      // at the end of the node, we use the node itself, if it is at
-      // the start, we use the node before it, and in any other
-      // case, we look up the child before the cursor and use that.
-      else {
-        if (offset == node.childNodes.length)
-          return topLevelNodeAt(node, container);
-        else if (offset == 0)
-          return topLevelNodeBefore(node, container);
-        else
-          return topLevelNodeAt(node.childNodes[offset - 1], container);
-      }
-    };
-
-    select.focusAfterNode = function(node, container) {
-      var win = container.ownerDocument.defaultView,
-          range = win.document.createRange();
-      range.setStartBefore(container.firstChild || container);
-      // In Opera, setting the end of a range at the end of a line
-      // (before a BR) will cause the cursor to appear on the next
-      // line, so we set the end inside of the start node when
-      // possible.
-      if (node && !node.firstChild)
-        range.setEndAfter(node);
-      else if (node)
-        range.setEnd(node, node.childNodes.length);
-      else
-        range.setEndBefore(container.firstChild || container);
-      range.collapse(false);
-      selectRange(range, win);
-    };
-
-    select.somethingSelected = function(win) {
-      var range = selectionRange(win);
-      return range && !range.collapsed;
-    };
-
-     // Insert a custom string at current cursor position (added for t3editor)
-     select.insertTextAtCursor = function(window, text) {
-            var selection = window.document.selection;
-            if (selection) {
-                    var range = selection.createRange();
-                    range.pasteHTML(text);
-                    range.collapse(false);
-                    range.select();
-            }
-     };
-
-    function insertNodeAtCursor(window, node) {
-      var range = selectionRange(window);
-      if (!range) return;
-
-      range.deleteContents();
-      range.insertNode(node);
-      range.setEndAfter(node);
-      range.collapse(false);
-      selectRange(range, window);
-      return node;
-    }
-
-    select.insertNewlineAtCursor = function(window) {
-      insertNodeAtCursor(window, window.document.createElement("BR"));
-    };
-
-    select.insertTabAtCursor = function(window) {
-      insertNodeAtCursor(window, window.document.createTextNode(fourSpaces));
-    };
-
-    select.cursorPos = function(container, start) {
-      var range = selectionRange(window);
-      if (!range) return;
-
-      var topNode = select.selectionTopNode(container, start);
-      while (topNode && topNode.nodeName != "BR")
-        topNode = topNode.previousSibling;
-
-      range = range.cloneRange();
-      range.collapse(start);
-      if (topNode)
-        range.setStartAfter(topNode);
-      else
-        range.setStartBefore(container);
-      return {node: topNode, offset: range.toString().length};
-    };
-
-    select.setCursorPos = function(container, from, to) {
-      var win = container.ownerDocument.defaultView,
-          range = win.document.createRange();
-
-      function setPoint(node, offset, side) {
-        if (!node)
-          node = container.firstChild;
-        else
-          node = node.nextSibling;
-
-        if (!node)
-          return;
-
-        if (offset == 0) {
-          range["set" + side + "Before"](node);
-          return true;
-        }
-
-        var backlog = []
-        function decompose(node) {
-          if (node.nodeType == 3)
-            backlog.push(node);
-          else
-            forEach(node.childNodes, decompose);
-        }
-        while (true) {
-          while (node && !backlog.length) {
-            decompose(node);
-            node = node.nextSibling;
-          }
-          var cur = backlog.shift();
-          if (!cur) return false;
-
-          var length = cur.nodeValue.length;
-          if (length >= offset) {
-            range["set" + side](cur, offset);
-            return true;
-          }
-          offset -= length;
-        }
-      }
-
-      to = to || from;
-      if (setPoint(to.node, to.offset, "End") && setPoint(from.node, from.offset, "Start"))
-        selectRange(range, win);
-    };
-
-    select.scrollToCursor = function(container) {
-      var body = container.ownerDocument.body, win = container.ownerDocument.defaultView;
-      var element = select.selectionTopNode(container, true) || container.firstChild;
-      
-      // In Opera, BR elements *always* have a scrollTop property of zero. Go Opera.
-      while (element && !element.offsetTop)
-        element = element.previousSibling;
-
-      var y = 0, pos = element;
-      while (pos && pos.offsetParent) {
-        y += pos.offsetTop;
-        pos = pos.offsetParent;
-      }
-
-      var screen_y = y - body.scrollTop;
-      if (screen_y < 0 || screen_y > win.innerHeight - 10)
-        win.scrollTo(0, y);
-    };
-  }
-})();
diff --git a/typo3/sysext/t3editor/jslib/codemirror/stringstream.js b/typo3/sysext/t3editor/jslib/codemirror/stringstream.js
deleted file mode 100644 (file)
index e320f8b..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/* String streams are the things fed to parsers (which can feed them
- * to a tokenizer if they want). They provide peek and next methods
- * for looking at the current character (next 'consumes' this
- * character, peek does not), and a get method for retrieving all the
- * text that was consumed since the last time get was called.
- *
- * An easy mistake to make is to let a StopIteration exception finish
- * the token stream while there are still characters pending in the
- * string stream (hitting the end of the buffer while parsing a
- * token). To make it easier to detect such errors, the strings throw
- * an exception when this happens.
- */
-
-// Make a string stream out of an iterator that returns strings. This
-// is applied to the result of traverseDOM (see codemirror.js), and
-// the resulting stream is fed to the parser.
-window.stringStream = function(source){
-  source = iter(source);
-  // String that's currently being iterated over.
-  var current = "";
-  // Position in that string.
-  var pos = 0;
-  // Accumulator for strings that have been iterated over but not
-  // get()-ed yet.
-  var accum = "";
-  // Make sure there are more characters ready, or throw
-  // StopIteration.
-  function ensureChars() {
-    while (pos == current.length) {
-      accum += current;
-      current = ""; // In case source.next() throws
-      pos = 0;
-      try {current = source.next();}
-      catch (e) {
-        if (e != StopIteration) throw e;
-        else return false;
-      }
-    }
-    return true;
-  }
-
-  return {
-    // Return the next character in the stream.
-    peek: function() {
-      if (!ensureChars()) return null;
-      return current.charAt(pos);
-    },
-    // Get the next character, throw StopIteration if at end, check
-    // for unused content.
-    next: function() {
-      if (!ensureChars()) {
-        if (accum.length > 0)
-          throw "End of stringstream reached without emptying buffer ('" + accum + "').";
-        else
-          throw StopIteration;
-      }
-      return current.charAt(pos++);
-    },
-    // Return the characters iterated over since the last call to
-    // .get().
-    get: function() {
-      var temp = accum;
-      accum = "";
-      if (pos > 0){
-        temp += current.slice(0, pos);
-        current = current.slice(pos);
-        pos = 0;
-      }
-      return temp;
-    },
-    // Push a string back into the stream.
-    push: function(str) {
-      current = current.slice(0, pos) + str + current.slice(pos);
-    },
-    lookAhead: function(str, consume, skipSpaces, caseInsensitive) {
-      function cased(str) {return caseInsensitive ? str.toLowerCase() : str;}
-      str = cased(str);
-      var found = false;
-
-      var _accum = accum, _pos = pos;
-      if (skipSpaces) this.nextWhile(matcher(/[\s\u00a0]/));
-
-      while (true) {
-        var end = pos + str.length, left = current.length - pos;
-        if (end <= current.length) {
-          found = str == cased(current.slice(pos, end));
-          pos = end;
-          break;
-        }
-        else if (str.slice(0, left) == cased(current.slice(pos))) {
-          accum += current; current = "";
-          try {current = source.next();}
-          catch (e) {break;}
-          pos = 0;
-          str = str.slice(left);
-        }
-        else {
-          break;
-        }
-      }
-
-      if (!(found && consume)) {
-        current = accum.slice(_accum.length) + current;
-        pos = _pos;
-        accum = _accum;
-      }
-
-      return found;
-    },
-
-    // Utils built on top of the above
-    more: function() {
-      return this.peek() !== null;
-    },
-    applies: function(test) {
-      var next = this.peek();
-      return (next !== null && test(next));
-    },
-    nextWhile: function(test) {
-      while (this.applies(test))
-        this.next();
-    },
-    equals: function(ch) {
-      return ch === this.peek();
-    },
-    endOfLine: function() {
-      var next = this.peek();
-      return next == null || next == "\n";
-    }
-  };
-};
diff --git a/typo3/sysext/t3editor/jslib/codemirror/tokenize.js b/typo3/sysext/t3editor/jslib/codemirror/tokenize.js
deleted file mode 100644 (file)
index 071970c..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-// A framework for simple tokenizers. Takes care of newlines and
-// white-space, and of getting the text from the source stream into
-// the token object. A state is a function of two arguments -- a
-// string stream and a setState function. The second can be used to
-// change the tokenizer's state, and can be ignored for stateless
-// tokenizers. This function should advance the stream over a token
-// and return a string or object containing information about the next
-// token, or null to pass and have the (new) state be called to finish
-// the token. When a string is given, it is wrapped in a {style, type}
-// object. In the resulting object, the characters consumed are stored
-// under the content property. Any whitespace following them is also
-// automatically consumed, and added to the value property. (Thus,
-// content is the actual meaningful part of the token, while value
-// contains all the text it spans.)
-
-function tokenizer(source, state) {
-  // Newlines are always a separate token.
-  function isWhiteSpace(ch) {
-    // The messy regexp is because IE's regexp matcher is of the
-    // opinion that non-breaking spaces are no whitespace.
-    return ch != "\n" && /^[\s\u00a0]*$/.test(ch);
-  }
-
-  var tokenizer = {
-    state: state,
-
-    take: function(type) {
-      if (typeof(type) == "string")
-        type = {style: type, type: type};
-
-      type.content = (type.content || "") + source.get();
-      if (!/\n$/.test(type.content))
-        source.nextWhile(isWhiteSpace);
-      type.value = type.content + source.get();
-      return type;
-    },
-
-    next: function () {
-      if (!source.more()) throw StopIteration;
-
-      var type;
-      if (source.equals("\n")) {
-        source.next();
-        return this.take("whitespace");
-      }
-      
-      if (source.applies(isWhiteSpace))
-        type = "whitespace";
-      else
-        while (!type)
-          type = this.state(source, function(s) {tokenizer.state = s;});
-
-      return this.take(type);
-    }
-  };
-  return tokenizer;
-}
diff --git a/typo3/sysext/t3editor/jslib/codemirror/tokenizejavascript.js b/typo3/sysext/t3editor/jslib/codemirror/tokenizejavascript.js
deleted file mode 100644 (file)
index bf8d2a1..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-/* Tokenizer for JavaScript code */
-
-var tokenizeJavaScript = (function() {
-  // Advance the stream until the given character (not preceded by a
-  // backslash) is encountered, or the end of the line is reached.
-  function nextUntilUnescaped(source, end) {
-    var escaped = false;
-    var next;
-    while (!source.endOfLine()) {
-      var next = source.next();
-      if (next == end && !escaped)
-        return false;
-      escaped = !escaped && next == "\\";
-    }
-    return escaped;
-  }
-
-  // A map of JavaScript's keywords. The a/b/c keyword distinction is
-  // very rough, but it gives the parser enough information to parse
-  // correct code correctly (we don't care that much how we parse
-  // incorrect code). The style information included in these objects
-  // is used by the highlighter to pick the correct CSS style for a
-  // token.
-  var keywords = function(){
-    function result(type, style){
-      return {type: type, style: style};
-    }
-    // keywords that take a parenthised expression, and then a
-    // statement (if)
-    var keywordA = result("keyword a", "js-keyword");
-    // keywords that take just a statement (else)
-    var keywordB = result("keyword b", "js-keyword");
-    // keywords that optionally take an expression, and form a
-    // statement (return)
-    var keywordC = result("keyword c", "js-keyword");
-    var operator = result("operator", "js-keyword");
-    var atom = result("atom", "js-atom");
-    return {
-      "if": keywordA, "switch": keywordA, "while": keywordA, "with": keywordA,
-      "else": keywordB, "do": keywordB, "try": keywordB, "finally": keywordB,
-      "return": keywordC, "break": keywordC, "continue": keywordC, "new": keywordC, "delete": keywordC, "throw": keywordC,
-      "in": operator, "typeof": operator, "instanceof": operator,
-      "var": result("var", "js-keyword"), "function": result("function", "js-keyword"), "catch": result("catch", "js-keyword"),
-      "for": result("for", "js-keyword"), 
-      "case": result("case", "js-keyword"), "default": result("default", "js-keyword"),
-      "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom
-    };
-  }();
-
-  // Some helper regexp matchers.
-  var isOperatorChar = matcher(/[+\-*&%\/=<>!?|]/);
-  var isDigit = matcher(/[0-9]/);
-  var isHexDigit = matcher(/[0-9A-Fa-f]/);
-  var isWordChar = matcher(/[\w\$_]/);
-
-  // Wrapper around jsToken that helps maintain parser state (whether
-  // we are inside of a multi-line comment and whether the next token
-  // could be a regular expression).
-  function jsTokenState(inside, regexp) {
-    return function(source, setState) {
-      var newInside = inside;
-      var type = jsToken(inside, regexp, source, function(c) {newInside = c;});
-      var newRegexp = type.type == "operator" || type.type == "keyword c" || type.type.match(/^[\[{}\(,;:]$/);
-      if (newRegexp != regexp || newInside != inside)
-        setState(jsTokenState(newInside, newRegexp));
-      return type;
-    };
-  }
-
-  // The token reader, inteded to be used by the tokenizer from
-  // tokenize.js (through jsTokenState). Advances the source stream
-  // over a token, and returns an object containing the type and style
-  // of that token.
-  function jsToken(inside, regexp, source, setInside) {
-    function readHexNumber(){
-      source.next(); // skip the 'x'
-      source.nextWhile(isHexDigit);
-      return {type: "number", style: "js-atom"};
-    }
-
-    function readNumber() {
-      source.nextWhile(isDigit);
-      if (source.equals(".")){
-        source.next();
-        source.nextWhile(isDigit);
-      }
-      if (source.equals("e") || source.equals("E")){
-        source.next();
-        if (source.equals("-"))
-          source.next();
-        source.nextWhile(isDigit);
-      }
-      return {type: "number", style: "js-atom"};
-    }
-    // Read a word, look it up in keywords. If not found, it is a
-    // variable, otherwise it is a keyword of the type found.
-    function readWord() {
-      source.nextWhile(isWordChar);
-      var word = source.get();
-      var known = keywords.hasOwnProperty(word) && keywords.propertyIsEnumerable(word) && keywords[word];
-      return known ? {type: known.type, style: known.style, content: word} :
-      {type: "variable", style: "js-variable", content: word};
-    }
-    function readRegexp() {
-      nextUntilUnescaped(source, "/");
-      source.nextWhile(matcher(/[gi]/));
-      return {type: "regexp", style: "js-string"};
-    }
-    // Mutli-line comments are tricky. We want to return the newlines
-    // embedded in them as regular newline tokens, and then continue
-    // returning a comment token for every line of the comment. So
-    // some state has to be saved (inside) to indicate whether we are
-    // inside a /* */ sequence.
-    function readMultilineComment(start){
-      var newInside = "/*";
-      var maybeEnd = (start == "*");
-      while (true) {
-        if (source.endOfLine())
-          break;
-        var next = source.next();
-        if (next == "/" && maybeEnd){
-          newInside = null;
-          break;
-        }
-        maybeEnd = (next == "*");
-      }
-      setInside(newInside);
-      return {type: "comment", style: "js-comment"};
-    }
-    function readOperator() {
-      source.nextWhile(isOperatorChar);
-      return {type: "operator", style: "js-operator"};
-    }
-    function readString(quote) {
-      var endBackSlash = nextUntilUnescaped(source, quote);
-      setInside(endBackSlash ? quote : null);
-      return {type: "string", style: "js-string"};
-    }
-
-    // Fetch the next token. Dispatches on first character in the
-    // stream, or first two characters when the first is a slash.
-    if (inside == "\"" || inside == "'")
-      return readString(inside);
-    var ch = source.next();
-    if (inside == "/*")
-      return readMultilineComment(ch);
-    else if (ch == "\"" || ch == "'")
-      return readString(ch);
-    // with punctuation, the type of the token is the symbol itself
-    else if (/[\[\]{}\(\),;\:\.]/.test(ch))
-      return {type: ch, style: "js-punctuation"};
-    else if (ch == "0" && (source.equals("x") || source.equals("X")))
-      return readHexNumber();
-    else if (isDigit(ch))
-      return readNumber();
-    else if (ch == "/"){
-      if (source.equals("*"))
-      { source.next(); return readMultilineComment(ch); }
-      else if (source.equals("/"))
-      { nextUntilUnescaped(source, null); return {type: "comment", style: "js-comment"};}
-      else if (regexp)
-        return readRegexp();
-      else
-        return readOperator();
-    }
-    else if (isOperatorChar(ch))
-      return readOperator();
-    else
-      return readWord();
-  }
-
-  // The external interface to the tokenizer.
-  return function(source, startState) {
-    return tokenizer(source, startState || jsTokenState(false, true));
-  };
-})();
diff --git a/typo3/sysext/t3editor/jslib/codemirror/tokenizetyposcript.js b/typo3/sysext/t3editor/jslib/codemirror/tokenizetyposcript.js
deleted file mode 100644 (file)
index 2b86396..0000000
+++ /dev/null
@@ -1,1368 +0,0 @@
-/* Tokenizer for TypoScript code
- *
- * based on tokenizejavascript.js by Marijn Haverbeke
- */
-
-// List of "reserved" word in typoscript and a css-class
-var typoscriptWords = {
-       '_CSS_DEFAULT_STYLE': 'keyword',
-       '_DEFAULT_PI_VARS': 'keyword',
-       '_GIFBUILDER': 'keyword',
-       '_LOCAL_LANG': 'keyword',
-       'CARRAY': 'keyword',
-       'CASE': 'keyword',
-       'CLEARGIF': 'keyword',
-       'COA': 'keyword',
-       'COA_INT': 'keyword',
-       'COBJ_ARRAY': 'keyword',
-       'COLUMNS': 'keyword',
-       'CONFIG': 'keyword',
-       'CONSTANTS': 'keyword',
-       'CONTENT': 'keyword',
-       'CTABLE': 'keyword',
-       'CType': 'keyword',
-       'DB': 'keyword',
-       'DOCUMENT_BODY': 'keyword',
-       'EDITPANEL': 'keyword',
-       'EFFECT': 'keyword',
-       'FE_DATA': 'keyword',
-       'FE_TABLE': 'keyword',
-       'FEData': 'keyword',
-       'FILE': 'keyword',
-       'FORM': 'keyword',
-       'FRAME': 'keyword',
-       'FRAMESET': 'keyword',
-       'GIFBUILDER': 'keyword',
-       'global': 'keyword',
-       'globalString': 'keyword',
-       'globalVar': 'keyword',
-       'GMENU': 'keyword',
-       'GMENU_FOLDOUT': 'keyword',
-       'GMENU_LAYERS': 'keyword',
-       'GP': 'keyword',
-       'HMENU': 'keyword',
-       'HRULER': 'keyword',
-       'HTML': 'keyword',
-       'IENV': 'keyword',
-       'IMAGE': 'keyword',
-       'IMG_RESOURCE': 'keyword',
-       'IMGMENU': 'keyword',
-       'IMGMENUITEM': 'keyword',
-       'IMGTEXT': 'keyword',
-       'INCLUDE_TYPOSCRIPT': 'keyword',
-       'includeLibs': 'keyword',
-       'JSMENU': 'keyword',
-       'JSMENUITEM': 'keyword',
-       'LIT': 'keyword',
-       'LOAD_REGISTER': 'keyword',
-       'META': 'keyword',
-       'MULTIMEDIA': 'keyword',
-       'OTABLE': 'keyword',
-       'PAGE': 'keyword',
-       'PAGE_TARGET': 'keyword',
-       'PAGE_TSCONFIG_ID': 'keyword',
-       'PAGE_TSCONFIG_IDLIST': 'keyword',
-       'PAGE_TSCONFIG_STR': 'keyword',
-       'PHP_SCRIPT': 'keyword',
-       'PHP_SCRIPT_EXT': 'keyword',
-       'PHP_SCRIPT_INT': 'keyword',
-       'RECORDS': 'keyword',
-       'REMOTE_ADDR': 'keyword',
-       'RESTORE_REGISTER': 'keyword',
-       'RTE': 'keyword',
-       'SEARCHRESULT': 'keyword',
-       'SHARED': 'keyword',
-       'TCAdefaults': 'keyword',
-       'TCEFORM': 'keyword',
-       'TCEMAIN': 'keyword',
-       'TEMPLATE': 'keyword',
-       'TEXT': 'keyword',
-       'TMENU': 'keyword',
-       'TMENU_LAYERS': 'keyword',
-       'TMENUITEM': 'keyword',
-       'TSFE': 'keyword',
-       'USER': 'keyword',
-       'USER_INT': 'keyword',
-       
-       'userFunc': 'keyword',
-
-       '_offset': 'reserved',
-       'absRefPrefix': 'reserved',
-       'accessibility': 'reserved',
-       'accessKey': 'reserved',
-       'addAttributes': 'reserved',
-       'addExtUrlsAndShortCuts': 'reserved',
-       'addItems': 'reserved',
-       'additionalHeaders': 'reserved',
-       'additionalParams': 'reserved',
-       'addParams': 'reserved',
-       'addQueryString': 'reserved',
-       'adjustItemsH': 'reserved',
-       'adjustSubItemsH': 'reserved',
-       'adminPanelStyles': 'reserved',
-       'after': 'reserved',
-       'afterImg': 'reserved',
-       'afterImgLink': 'reserved',
-       'afterImgTagParams': 'reserved',
-       'afterROImg': 'reserved',
-       'afterWrap': 'reserved',
-       'age': 'reserved',
-       'alertPopups': 'reserved',
-       'align': 'reserved',
-       'allow': 'reserved',
-       'allowCaching': 'reserved',
-       'allowedAttribs': 'reserved',
-       'allowedClasses': 'reserved',
-       'allowedCols': 'reserved',
-       'allowEdit': 'reserved',
-       'allowedNewTables': 'reserved',
-       'allowNew': 'reserved',
-       'allowTags': 'reserved',
-       'allowTVlisting': 'reserved',
-       'allSaveFunctions': 'reserved',
-       'allStdWrap': 'reserved',
-       'allWrap': 'reserved',
-       'alternateBgColors': 'reserved',
-       'alternativeSortingField': 'reserved',
-       'alternativeTempPath': 'reserved',
-       'altImgResource': 'reserved',
-       'altLabels': 'reserved',
-       'altTarget': 'reserved',
-       'altText': 'reserved',
-       'altUrl': 'reserved',
-       'altUrl_noDefaultParams': 'reserved',
-       'altWrap': 'reserved',
-       'always': 'reserved',
-       'alwaysActivePIDlist': 'reserved',
-       'alwaysLink': 'reserved',
-       'alwaysShowClickMenuInTopFrame': 'reserved',
-       'andWhere': 'reserved',
-       'angle': 'reserved',
-       'antiAlias': 'reserved',
-       'append': 'reserved',
-       'applyTotalH': 'reserved',
-       'applyTotalW': 'reserved',
-       'archive': 'reserved',
-       'archiveTypoLink': 'reserved',
-       'arrayReturnMode': 'reserved',
-       'arrowACT': 'reserved',
-       'arrowImgParams': 'reserved',
-       'arrowNO': 'reserved',
-       'ATagAfterWrap': 'reserved',
-       'ATagBeforeWrap': 'reserved',
-       'ATagParams': 'reserved',
-       'ATagTitle': 'reserved',
-       'attribute': 'reserved',
-       'autoInsertPID': 'reserved',
-       'autoLevels': 'reserved',
-       'autonumber': 'reserved',
-       'backColor': 'reserved',
-       'background': 'reserved',
-       'badMess': 'reserved',
-       'baseURL': 'reserved',
-       'before': 'reserved',
-       'beforeImg': 'reserved',
-       'beforeImgLink': 'reserved',
-       'beforeImgTagParams': 'reserved',
-       'beforeROImg': 'reserved',
-       'beforeWrap': 'reserved',
-       'begin': 'reserved',
-       'beLoginLinkIPList': 'reserved',
-       'beLoginLinkIPList_login': 'reserved',
-       'beLoginLinkIPList_logout': 'reserved',
-       'bgCol': 'reserved',
-       'bgImg': 'reserved',
-       'blankStrEqFalse': 'reserved',
-       'blur': 'reserved',
-       'bm': 'reserved',
-       'bodyTag': 'reserved',
-       'bodyTagAdd': 'reserved',
-       'bodyTagCObject': 'reserved',
-       'bodyTagMargins': 'reserved',
-       'bodytext': 'reserved',
-       'border': 'reserved',
-       'borderCol': 'reserved',
-       'bordersWithin': 'reserved',
-       'borderThick': 'reserved',
-       'bottomBackColor': 'reserved',
-       'bottomContent': 'reserved',
-       'bottomHeight': 'reserved',
-       'bottomImg': 'reserved',
-       'bottomImg_mask': 'reserved',
-       'br': 'reserved',
-       'brTag': 'reserved',
-       'bullet': 'reserved',
-       'bulletlist': 'reserved',
-       'bytes': 'reserved',
-       'cache_clearAtMidnight': 'reserved',
-       'cache_period': 'reserved',
-       'caption': 'reserved',
-       'caption_stdWrap': 'reserved',
-       'captionAlign': 'reserved',
-       'captionHeader': 'reserved',
-       'captionSplit': 'reserved',
-       'case': 'reserved',
-       'casesensitiveComp': 'reserved',
-       'cellpadding': 'reserved',
-       'cellspacing': 'reserved',
-       'centerImgACT': 'reserved',
-       'centerImgCUR': 'reserved',
-       'centerImgNO': 'reserved',
-       'centerLeftImgACT': 'reserved',
-       'centerLeftImgCUR': 'reserved',
-       'centerLeftImgNO': 'reserved',
-       'centerRightImgACT': 'reserved',
-       'centerRightImgCUR': 'reserved',
-       'centerRightImgNO': 'reserved',
-       'char': 'reserved',
-       'charcoal': 'reserved',
-       'charMapConfig': 'reserved',
-       'check': 'reserved',
-       'class': 'reserved',
-       'classesAnchor': 'reserved',
-       'classesCharacter': 'reserved',
-       'classesImage': 'reserved',
-       'classesParagraph': 'reserved',
-       'classicPageEditMode': 'reserved',
-       'clear': 'reserved',
-       'clearCache': 'reserved',
-       'clearCache_disable': 'reserved',
-       'clearCache_pageGrandParent': 'reserved',
-       'clearCache_pageSiblingChildren': 'reserved',
-       'clearCacheCmd': 'reserved',
-       'clearCacheLevels': 'reserved',
-       'clearCacheOfPages': 'reserved',
-       'clickMenuTimeOut': 'reserved',
-       'clickTitleMode': 'reserved',
-       'clipboardNumberPads': 'reserved',
-       'cMargins': 'reserved',
-       'cObjNum': 'reserved',
-       'collapse': 'reserved',
-       'color': 'reserved',
-       'color1': 'reserved',
-       'color2': 'reserved',
-       'color3': 'reserved',
-       'color4': 'reserved',
-       'colors': 'reserved',
-       'colour': 'reserved',
-       'colPos_list': 'reserved',
-       'colRelations': 'reserved',
-       'cols': 'reserved',
-       'colSpace': 'reserved',
-       'comment_auto': 'reserved',
-       'commentWrap': 'reserved',
-       'compensateFieldWidth': 'reserved',
-       'compX': 'reserved',
-       'compY': 'reserved',
-       'condensedMode': 'reserved',
-       'conf': 'reserved',
-       'constants': 'reserved',
-       'content_from_pid_allowOutsideDomain': 'reserved',
-       'contextMenu': 'reserved',
-       'copyLevels': 'reserved',
-       'count_HMENU_MENUOBJ': 'reserved',
-       'count_menuItems': 'reserved',
-       'count_MENUOBJ': 'reserved',
-       'create': 'reserved',
-       'createFoldersInEB': 'reserved',
-       'crop': 'reserved',
-       'csConv': 'reserved',
-       'CSS_inlineStyle': 'reserved',
-       'current': 'reserved',
-       'curUid': 'reserved',
-       'cWidth': 'reserved',
-       'data': 'reserved',
-       'dataWrap': 'reserved',
-       'date': 'reserved',
-       'date_stdWrap': 'reserved',
-       'datePrefix': 'reserved',
-       'debug': 'reserved',
-       'debugData': 'reserved',
-       'debugFunc': 'reserved',
-       'debugItemConf': 'reserved',
-       'debugRenumberedObject': 'reserved',
-       'default': 'reserved',
-       'defaultAlign': 'reserved',
-       'defaultCmd': 'reserved',
-       'defaultFileUploads': 'reserved',
-       'defaultHeaderType': 'reserved',
-       'defaultOutput': 'reserved',
-       'defaults': 'reserved',
-       'defaultType': 'reserved',
-       'delete': 'reserved',
-       'denyTags': 'reserved',
-       'depth': 'reserved',
-       'DESC': 'reserved',
-       'dimensions': 'reserved',
-       'directionLeft': 'reserved',
-       'directionUp': 'reserved',
-       'disableAdvanced': 'reserved',
-       'disableAllHeaderCode': 'reserved',
-       'disableAltText': 'reserved',
-       'disableBigButtons': 'reserved',
-       'disableCacheSelector': 'reserved',
-       'disableCharsetHeader': 'reserved',
-       'disableCMlayers': 'reserved',
-       'disabled': 'reserved',
-       'disableDelete': 'reserved',
-       'disableDocModuleInAB': 'reserved',
-       'disableDocSelector': 'reserved',
-       'disableHideAtCopy': 'reserved',
-       'disableIconLinkToContextmenu': 'reserved',
-       'disableItems': 'reserved',
-       'disableNewContentElementWizard': 'reserved',
-       'disableNoMatchingValueElement': 'reserved',
-       'disablePageExternalUrl': 'reserved',
-       'disablePrefixComment': 'reserved',
-       'disablePrependAtCopy': 'reserved',
-       'disableSearchBox': 'reserved',
-       'disableSingleTableView': 'reserved',
-       'disableTabInTextarea': 'reserved',
-       'displayActiveOnLoad': 'reserved',
-       'displayContent': 'reserved',
-       'displayFieldIcons': 'reserved',
-       'displayIcons': 'reserved',
-       'displayMessages': 'reserved',
-       'displayQueries': 'reserved',
-       'displayRecord': 'reserved',
-       'displayTimes': 'reserved',
-       'distributeX': 'reserved',
-       'distributeY': 'reserved',
-       'DIV': 'reserved',
-       'doctype': 'reserved',
-       'doctypeSwitch': 'reserved',
-       'doktype': 'reserved',
-       'doNotLinkIt': 'reserved',
-       'doNotShowLink': 'reserved',
-       'doNotStripHTML': 'reserved',
-       'dontCheckPid': 'reserved',
-       'dontFollowMouse': 'reserved',
-       'dontHideOnMouseUp': 'reserved',
-       'dontLinkIfSubmenu': 'reserved',
-       'dontShowPalettesOnFocusInAB': 'reserved',
-       'dontWrapInTable': 'reserved',
-       'doubleBrTag': 'reserved',
-       'doublePostCheck': 'reserved',
-       'dWorkArea': 'reserved',
-       'edge': 'reserved',
-       'edit_docModuleUplaod': 'reserved',
-       'edit_docModuleUpload': 'reserved',
-       'edit_RTE': 'reserved',
-       'edit_showFieldHelp': 'reserved',
-       'edit_wideDocument': 'reserved',
-       'editFieldsAtATime': 'reserved',
-       'editFormsOnPage': 'reserved',
-       'editIcons': 'reserved',
-       'editNoPopup': 'reserved',
-       'editPanel': 'reserved',
-       'elements': 'reserved',
-       'emailMeAtLogin': 'reserved',
-       'emailMess': 'reserved',
-       'emboss': 'reserved',
-       'enable': 'reserved',
-       'encapsLines': 'reserved',
-       'encapsLinesStdWrap': 'reserved',
-       'encapsTagList': 'reserved',
-       'entryLevel': 'reserved',
-       'equalH': 'reserved',
-       'everybody': 'reserved',
-       'excludeDoktypes': 'reserved',
-       'excludeUidList': 'reserved',
-       'expAll': 'reserved',
-       'expand': 'reserved',
-       'explode': 'reserved',
-       'ext': 'reserved',
-       'externalBlocks': 'reserved',
-       'extTarget': 'reserved',
-       'face': 'reserved',
-       'fe_adminLib': 'reserved',
-       'field': 'reserved',
-       'fieldOrder': 'reserved',
-       'fieldRequired': 'reserved',
-       'fields': 'reserved',
-       'fieldWrap': 'reserved',
-       'file': 'reserved',
-       'file1': 'reserved',
-       'file2': 'reserved',
-       'file3': 'reserved',
-       'file4': 'reserved',
-       'file5': 'reserved',
-       'filelink': 'reserved',
-       'filelist': 'reserved',
-       'firstLabel': 'reserved',
-       'firstLabelGeneral': 'reserved',
-       'fixAttrib': 'reserved',
-       'flip': 'reserved',
-       'flop': 'reserved',
-       'foldSpeed': 'reserved',
-       'foldTimer': 'reserved',
-       'fontColor': 'reserved',
-       'fontFile': 'reserved',
-       'fontOffset': 'reserved',
-       'fontSize': 'reserved',
-       'fontSizeMultiplicator': 'reserved',
-       'fontTag': 'reserved',
-       'forceDisplayFieldIcons': 'reserved',
-       'forceDisplayIcons': 'reserved',
-       'forceNoPopup': 'reserved',
-       'forceTemplateParsing': 'reserved',
-       'forceTypeValue': 'reserved',
-       'format': 'reserved',
-       'frame': 'reserved',
-       'frameReloadIfNotInFrameset': 'reserved',
-       'frameSet': 'reserved',
-       'freezeMouseover': 'reserved',
-       'ftu': 'reserved',
-       'function': 'reserved',
-       'gamma': 'reserved',
-       'gapBgCol': 'reserved',
-       'gapLineCol': 'reserved',
-       'gapLineThickness': 'reserved',
-       'gapWidth': 'reserved',
-       'get': 'reserved',
-       'getBorder': 'reserved',
-       'getLeft': 'reserved',
-       'getRight': 'reserved',
-       'globalNesting': 'reserved',
-       'goodMess': 'reserved',
-       'gray': 'reserved',
-       'group': 'reserved',
-       'groupBy': 'reserved',
-       'groupid': 'reserved',
-       'header': 'reserved',
-       'header_layout': 'reserved',
-       'headerComment': 'reserved',
-       'headerData': 'reserved',
-       'headerSpace': 'reserved',
-       'headTag': 'reserved',
-       'height': 'reserved',
-       'helpText': 'reserved',
-       'hidden': 'reserved',
-       'hiddenFields': 'reserved',
-       'hide': 'reserved',
-       'hideButCreateMap': 'reserved',
-       'hideMenuTimer': 'reserved',
-       'hideMenuWhenNotOver': 'reserved',
-       'hidePStyleItems': 'reserved',
-       'hideRecords': 'reserved',
-       'hideSubmoduleIcons': 'reserved',
-       'highColor': 'reserved',
-       'history': 'reserved',
-       'hover': 'reserved',
-       'hoverStyle': 'reserved',
-       'HTMLparser': 'reserved',
-       'HTMLparser_tags': 'reserved',
-       'htmlSpecialChars': 'reserved',
-       'htmlTag_dir': 'reserved',
-       'htmlTag_langKey': 'reserved',
-       'htmlTag_setParams': 'reserved',
-       'http': 'reserved',
-       'icon': 'reserved',
-       'icon_image_ext_list': 'reserved',
-       'icon_link': 'reserved',
-       'iconCObject': 'reserved',
-       'ifEmpty': 'reserved',
-       'image': 'reserved',
-       'image_compression': 'reserved',
-       'image_effects': 'reserved',
-       'image_frames': 'reserved',
-       'imageLinkWrap': 'reserved',
-       'imagePath': 'reserved',
-       'images': 'reserved',
-       'imageWrapIfAny': 'reserved',
-       'imgList': 'reserved',
-       'imgMap': 'reserved',
-       'imgMapExtras': 'reserved',
-       'imgMax': 'reserved',
-       'imgNameNotRandom': 'reserved',
-       'imgNamePrefix': 'reserved',
-       'imgObjNum': 'reserved',
-       'imgParams': 'reserved',
-       'imgPath': 'reserved',
-       'imgStart': 'reserved',
-       'import': 'reserved',
-       'inc': 'reserved',
-       'includeCSS': 'reserved',
-       'includeLibrary': 'reserved',
-       'includeNotInMenu': 'reserved',
-       'incT3Lib_htmlmail': 'reserved',
-       'index': 'reserved',
-       'index_descrLgd': 'reserved',
-       'index_enable': 'reserved',
-       'index_externals': 'reserved',
-       'inlineStyle2TempFile': 'reserved',
-       'innerStdWrap': 'reserved',
-       'innerStdWrap_all': 'reserved',
-       'innerWrap': 'reserved',
-       'innerWrap2': 'reserved',
-       'input': 'reserved',
-       'inputLevels': 'reserved',
-       'insertClassesFromRTE': 'reserved',
-       'insertData': 'reserved',
-       'insertDmailerBoundaries': 'reserved',
-       'intensity': 'reserved',
-       'intTarget': 'reserved',
-       'intval': 'reserved',
-       'invert': 'reserved',
-       'IProcFunc': 'reserved',
-       'itemArrayProcFunc': 'reserved',
-       'itemH': 'reserved',
-       'items': 'reserved',
-       'itemsProcFunc': 'reserved',
-       'iterations': 'reserved',
-       'join': 'reserved',
-       'JSWindow': 'reserved',
-       'JSwindow_params': 'reserved',
-       'jumpurl': 'reserved',
-       'jumpUrl': 'reserved',
-       'jumpurl_enable': 'reserved',
-       'jumpurl_mailto_disable': 'reserved',
-       'jumpUrl_transferSession': 'reserved',
-       'keep': 'reserved',
-       'keepEntries': 'reserved',
-       'keepNonMatchedTags': 'reserved',
-       'key': 'reserved',
-       'label': 'reserved',
-       'labelStdWrap': 'reserved',
-       'labelWrap': 'reserved',
-       'lang': 'reserved',
-       'language': 'reserved',
-       'language_alt': 'reserved',
-       'languageField': 'reserved',
-       'layer_menu_id': 'reserved',
-       'layerStyle': 'reserved',
-       'left': 'reserved',
-       'leftIcons': 'reserved',
-       'leftImgACT': 'reserved',
-       'leftImgCUR': 'reserved',
-       'leftImgNO': 'reserved',
-       'leftjoin': 'reserved',
-       'leftOffset': 'reserved',
-       'levels': 'reserved',
-       'leveluid': 'reserved',
-       'limit': 'reserved',
-       'line': 'reserved',
-       'lineColor': 'reserved',
-       'lineThickness': 'reserved',
-       'linkPrefix': 'reserved',
-       'linkTitleToSelf': 'reserved',
-       'linkVars': 'reserved',
-       'linkWrap': 'reserved',
-       'listNum': 'reserved',
-       'listOnlyInSingleTableView': 'reserved',
-       'lm': 'reserved',
-       'locale_all': 'reserved',
-       'localNesting': 'reserved',
-       'locationData': 'reserved',
-       'lockFilePath': 'reserved',
-       'lockPosition': 'reserved',
-       'lockPosition_addSelf': 'reserved',
-       'lockPosition_adjust': 'reserved',
-       'lockToIP': 'reserved',
-       'longdescURL': 'reserved',
-       'lowColor': 'reserved',
-       'lower': 'reserved',
-       'LR': 'reserved',
-       'mailto': 'reserved',
-       'main': 'reserved',
-       'mainScript': 'reserved',
-       'makelinks': 'reserved',
-       'markerWrap': 'reserved',
-       'mask': 'reserved',
-       'max': 'reserved',
-       'maxAge': 'reserved',
-       'maxAgeDays': 'reserved',
-       'maxChars': 'reserved',
-       'maxH': 'reserved',
-       'maxHeight': 'reserved',
-       'maxItems': 'reserved',
-       'maxW': 'reserved',
-       'maxWidth': 'reserved',
-       'maxWInText': 'reserved',
-       'mayNotCreateEditShortcuts': 'reserved',
-       'menu_type': 'reserved',
-       'menuBackColor': 'reserved',
-       'menuHeight': 'reserved',
-       'menuName': 'reserved',
-       'menuOffset': 'reserved',
-       'menuWidth': 'reserved',
-       'message_page_is_being_generated': 'reserved',
-       'message_preview': 'reserved',
-       'meta': 'reserved',
-       'metaCharset': 'reserved',
-       'method': 'reserved',
-       'min': 'reserved',
-       'minH': 'reserved',
-       'minItems': 'reserved',
-       'minW': 'reserved',
-       'mode': 'reserved',
-       'moduleMenuCollapsable': 'reserved',
-       'MP_defaults': 'reserved',
-       'MP_disableTypolinkClosestMPvalue': 'reserved',
-       'MP_mapRootPoints': 'reserved',
-       'name': 'reserved',
-       'navFrameResizable': 'reserved',
-       'navFrameWidth': 'reserved',
-       'nesting': 'reserved',
-       'netprintApplicationLink': 'reserved',
-       'neverHideAtCopy': 'reserved',
-       'newPageWiz': 'reserved',
-       'newRecordFromTable': 'reserved',
-       'newWindow': 'reserved',
-       'newWizards': 'reserved',
-       'next': 'reserved',
-       'niceText': 'reserved',
-       'nicetext': 'reserved',
-       'no_cache': 'reserved',
-       'no_search': 'reserved',
-       'noAttrib': 'reserved',
-       'noBlur': 'reserved',
-       'noCache': 'reserved',
-       'noCols': 'reserved',
-       'noCreateRecordsLink': 'reserved',
-       'noLink': 'reserved',
-       'noLinkUnderline': 'reserved',
-       'noMatchingValue_label': 'reserved',
-       'noMenuMode': 'reserved',
-       'nonCachedSubst': 'reserved',
-       'nonTypoTagStdWrap': 'reserved',
-       'nonTypoTagUserFunc': 'reserved',
-       'nonWrappedTag': 'reserved',
-       'noOrderBy': 'reserved',
-       'noPageTitle': 'reserved',
-       'noRows': 'reserved',
-       'noScaleUp': 'reserved',
-       'noStretchAndMarginCells': 'reserved',
-       'noThumbsInEB': 'reserved',
-       'noThumbsInRTEimageSelect': 'reserved',
-       'notification_email_charset': 'reserved',
-       'notification_email_encoding': 'reserved',
-       'notification_email_urlmode': 'reserved',
-       'noTrimWrap': 'reserved',
-       'noValueInsert': 'reserved',
-       'obj': 'reserved',
-       'offset': 'reserved',
-       'offsetWrap': 'reserved',
-       'onlineWorkspaceInfo': 'reserved',
-       'onlyCurrentPid': 'reserved',
-       'opacity': 'reserved',
-       'orderBy': 'reserved',
-       'outerWrap': 'reserved',
-       'outline': 'reserved',
-       'outputLevels': 'reserved',
-       'override': 'reserved',
-       'overrideAttribs': 'reserved',
-       'overrideEdit': 'reserved',
-       'overrideId': 'reserved',
-       'overridePageModule': 'reserved',
-       'overrideWithExtension': 'reserved',
-       'pageFrameObj': 'reserved',
-       'pageGenScript': 'reserved',
-       'pageTitleFirst': 'reserved',
-       'parameter': 'reserved',
-       'params': 'reserved',
-       'parseFunc': 'reserved',
-       'parser': 'reserved',
-       'password': 'reserved',
-       'path': 'reserved',
-       'permissions': 'reserved',
-       'pid_list': 'reserved',
-       'pidInList': 'reserved',
-       'pixelSpaceFontSizeRef': 'reserved',
-       'plaintextLib': 'reserved',
-       'plainTextStdWrap': 'reserved',
-       'postCObject': 'reserved',
-       'postLineBlanks': 'reserved',
-       'postLineChar': 'reserved',
-       'postLineLen': 'reserved',
-       'postUserFunc': 'reserved',
-       'postUserFuncInt': 'reserved',
-       'preBlanks': 'reserved',
-       'preCObject': 'reserved',
-       'prefix': 'reserved',
-       'prefixComment': 'reserved',
-       'prefixLocalAnchors': 'reserved',
-       'prefixRelPathWith': 'reserved',
-       'preIfEmptyListNum': 'reserved',
-       'preLineBlanks': 'reserved',
-       'preLineChar': 'reserved',
-       'preLineLen': 'reserved',
-       'prepend': 'reserved',
-       'preserveEntities': 'reserved',
-       'preUserFunc': 'reserved',
-       'prev': 'reserved',
-       'previewBorder': 'reserved',
-       'prevnextToSection': 'reserved',
-       'printheader': 'reserved',
-       'prioriCalc': 'reserved',
-       'proc': 'reserved',
-       'processScript': 'reserved',
-       'properties': 'reserved',
-       'protect': 'reserved',
-       'protectLvar': 'reserved',
-       'publish_levels': 'reserved',
-       'QEisDefault': 'reserved',
-       'quality': 'reserved',
-       'radio': 'reserved',
-       'radioWrap': 'reserved',
-       'range': 'reserved',
-       'rawUrlEncode': 'reserved',
-       'recipient': 'reserved',
-       'recursive': 'reserved',
-       'recursiveDelete': 'reserved',
-       'redirect': 'reserved',
-       'redirectToURL': 'reserved',
-       'reduceColors': 'reserved',
-       'register': 'reserved',
-       'relativeToParentLayer': 'reserved',
-       'relativeToTriggerItem': 'reserved',
-       'relPathPrefix': 'reserved',
-       'remap': 'reserved',
-       'remapTag': 'reserved',
-       'removeBadHTML': 'reserved',
-       'removeDefaultJS': 'reserved',
-       'removeIfEquals': 'reserved',
-       'removeIfFalse': 'reserved',
-       'removeItems': 'reserved',
-       'removeObjectsOfDummy': 'reserved',
-       'removePrependedNumbers': 'reserved',
-       'removeTags': 'reserved',
-       'removeWrapping': 'reserved',
-       'renderCharset': 'reserved',
-       'renderWrap': 'reserved',
-       'reset': 'reserved',
-       'resources': 'reserved',
-       'resultObj': 'reserved',
-       'returnLast': 'reserved',
-       'returnUrl': 'reserved',
-       'rightImgACT': 'reserved',
-       'rightImgCUR': 'reserved',
-       'rightImgNO': 'reserved',
-       'rightjoin': 'reserved',
-       'rm': 'reserved',
-       'rmTagIfNoAttrib': 'reserved',
-       'RO_chBgColor': 'reserved',
-       'rotate': 'reserved',
-       'rows': 'reserved',
-       'rowSpace': 'reserved',
-       'RTEfullScreenWidth': 'reserved',
-       'rules': 'reserved',
-       'sample': 'reserved',
-       'saveClipboard': 'reserved',
-       'saveDocNew': 'reserved',
-       'secondRow': 'reserved',
-       'section': 'reserved',
-       'sectionIndex': 'reserved',
-       'select': 'reserved',
-       'select_key': 'reserved',
-       'selectFields': 'reserved',
-       'separator': 'reserved',
-       'set': 'reserved',
-       'setContentToCurrent': 'reserved',
-       'setCurrent': 'reserved',
-       'setfixed': 'reserved',
-       'setFixedHeight': 'reserved',
-       'setFixedWidth': 'reserved',
-       'setJS_mouseOver': 'reserved',
-       'setJS_openPic': 'reserved',
-       'setOnly': 'reserved',
-       'shadow': 'reserved',
-       'sharpen': 'reserved',
-       'shear': 'reserved',
-       'short': 'reserved',
-       'shortcut': 'reserved',
-       'shortcut_onEditId_dontSetPageTree': 'reserved',
-       'shortcut_onEditId_keepExistingExpanded': 'reserved',
-       'shortcutFrame': 'reserved',
-       'shortcutGroups': 'reserved',
-       'shortcutIcon': 'reserved',
-       'show': 'reserved',
-       'showAccessRestrictedPages': 'reserved',
-       'showActive': 'reserved',
-       'showClipControlPanelsDespiteOfCMlayers': 'reserved',
-       'showFirst': 'reserved',
-       'showHiddenPages': 'reserved',
-       'showHiddenRecords': 'reserved',
-       'showHistory': 'reserved',
-       'showPageIdWithTitle': 'reserved',
-       'showTagFreeClasses': 'reserved',
-       'simulateDate': 'reserved',
-       'simulateStaticDocuments': 'reserved',
-       'simulateStaticDocuments_addTitle': 'reserved',
-       'simulateStaticDocuments_dontRedirectPathInfoError': 'reserved',
-       'simulateStaticDocuments_noTypeIfNoTitle': 'reserved',
-       'simulateStaticDocuments_pEnc': 'reserved',
-       'simulateStaticDocuments_pEnc_onlyP': 'reserved',
-       'simulateUserGroup': 'reserved',
-       'singlePid': 'reserved',
-       'site_author': 'reserved',
-       'site_reserved': 'reserved',
-       'sitetitle': 'reserved',
-       'siteUrl': 'reserved',
-       'size': 'reserved',
-       'smallFormFields': 'reserved',
-       'solarize': 'reserved',
-       'sorting': 'reserved',
-       'source': 'reserved',
-       'space': 'reserved',
-       'spaceAfter': 'reserved',
-       'spaceBefore': 'reserved',
-       'spaceBelowAbove': 'reserved',
-       'spaceLeft': 'reserved',
-       'spaceRight': 'reserved',
-       'spacing': 'reserved',
-       'spamProtectEmailAddresses': 'reserved',
-       'spamProtectEmailAddresses_atSubst': 'reserved',
-       'spamProtectEmailAddresses_lastDotSubst': 'reserved',
-       'special': 'reserved',
-       'splitChar': 'reserved',
-       'splitRendering': 'reserved',
-       'src': 'reserved',
-       'startInTaskCenter': 'reserved',
-       'stayFolded': 'reserved',
-       'stdheader': 'reserved',
-       'stdWrap': 'reserved',
-       'stdWrap2': 'reserved',
-       'strftime': 'reserved',
-       'stripHtml': 'reserved',
-       'styles': 'reserved',
-       'stylesheet': 'reserved',
-       'submenuObjSuffixes': 'reserved',
-       'subMenuOffset': 'reserved',
-       'submit': 'reserved',
-       'subst_elementUid': 'reserved',
-       'substMarksSeparately': 'reserved',
-       'substring': 'reserved',
-       'swirl': 'reserved',
-       'sword': 'reserved',
-       'sword_noMixedCase': 'reserved',
-       'SWORD_PARAMS': 'reserved',
-       'sword_standAlone': 'reserved',
-       'sys_language_mode': 'reserved',
-       'sys_language_overlay': 'reserved',
-       'sys_language_softMergeIfNotBlank': 'reserved',
-       'sys_language_uid': 'reserved',
-       'table': 'reserved',
-       'tableCellColor': 'reserved',
-       'tableParams': 'reserved',
-       'tables': 'reserved',
-       'tableStdWrap': 'reserved',
-       'tableStyle': 'reserved',
-       'tableWidth': 'reserved',
-       'tags': 'reserved',
-       'target': 'reserved',
-       'TDparams': 'reserved',
-       'templateContent': 'reserved',
-       'templateFile': 'reserved',
-       'text': 'reserved',
-       'textarea': 'reserved',
-       'textMargin': 'reserved',
-       'textMargin_outOfText': 'reserved',
-       'textMaxLength': 'reserved',
-       'textObjNum': 'reserved',
-       'textPos': 'reserved',
-       'textStyle': 'reserved',
-       'thickness': 'reserved',
-       'thumbnailsByDefault': 'reserved',
-       'tile': 'reserved',
-       'time_stdWrap': 'reserved',
-       'tipafriendLib': 'reserved',
-       'title': 'reserved',
-       'titleLen': 'reserved',
-       'titleTagFunction': 'reserved',
-       'titleText': 'reserved',
-       'tm': 'reserved',
-       'token': 'reserved',
-       'topOffset': 'reserved',
-       'totalWidth': 'reserved',
-       'transparentBackground': 'reserved',
-       'transparentColor': 'reserved',
-       'trim': 'reserved',
-       'tsdebug_tree': 'reserved',
-       'type': 'reserved',
-       'typeNum': 'reserved',
-       'types': 'reserved',
-       'typolinkCheckRootline': 'reserved',
-       'uidInList': 'reserved',
-       'unset': 'reserved',
-       'uploadFieldsInTopOfEB': 'reserved',
-       'uploads': 'reserved',
-       'upper': 'reserved',
-       'useCacheHash': 'reserved',
-       'useLargestItemX': 'reserved',
-       'useLargestItemY': 'reserved',
-       'user': 'reserved',
-       'userdefined': 'reserved',
-       'userfunction': 'reserved',
-       'userid': 'reserved',
-       'userIdColumn': 'reserved',
-       'USERNAME_substToken': 'reserved',
-       'userProc': 'reserved',
-       'value': 'reserved',
-       'valueArray': 'reserved',
-       'wave': 'reserved',
-       'where': 'reserved',
-       'width': 'reserved',
-       'wiz': 'reserved',
-       'wordSpacing': 'reserved',
-       'workArea': 'reserved',
-       'wrap': 'reserved',
-       'wrap1': 'reserved',
-       'wrap2': 'reserved',
-       'wrap3': 'reserved',
-       'wrapAfterTags': 'reserved',
-       'wrapAlign': 'reserved',
-       'wrapFieldName': 'reserved',
-       'wrapItemAndSub': 'reserved',
-       'wrapNonWrappedLines': 'reserved',
-       'wraps': 'reserved',
-       'xhtml_cleaning': 'reserved',
-       'xmlprologue': 'reserved',
-       'xPosOffset': 'reserved',
-       'yPosOffset': 'reserved',
-
-       'admPanel': 'keyword2',
-       'alt_print': 'keyword2',
-       'auth': 'keyword2',
-       'browser': 'keyword2',
-       'cache': 'keyword2',
-       'CHECK': 'keyword2',
-       'cObj': 'keyword2',
-       'cObject': 'keyword2',
-       'COMMENT': 'keyword2',
-       'config': 'keyword2',
-       'content': 'keyword2',
-       'copy': 'keyword2',
-       'CSS_inlineStyle': 'keyword2',
-       'cut': 'keyword2',
-       'dataArray': 'keyword2',
-       'dayofmonth': 'keyword2',
-       'dayofweek': 'keyword2',
-       'db_list': 'keyword2',
-       'device': 'keyword2',
-       'dynCSS': 'keyword2',
-       'edit': 'keyword2',
-       'edit_access': 'keyword2',
-       'edit_pageheader': 'keyword2',
-       'folder': 'keyword2',
-       'folderTree': 'keyword2',
-       'foldoutMenu': 'keyword2',
-       'Functions': 'keyword2',
-       'gmenu_foldout': 'keyword2',
-       'gmenu_layers': 'keyword2',
-       'hostname': 'keyword2',
-       'hour': 'keyword2',
-       'imgList': 'keyword2',
-       'imgResource': 'keyword2',
-       'imgText': 'keyword2',
-       'info': 'keyword2',
-       'IP': 'keyword2',
-       'jsmenu': 'keyword2',
-       'JSwindow': 'keyword2',
-       'LABEL': 'keyword2',
-       'layout': 'keyword2',
-       'lib': 'keyword2',
-       'loginUser': 'keyword2',
-       'marks': 'keyword2',
-       'minute': 'keyword2',
-       'mod': 'keyword2',
-       'module': 'keyword2',
-       'month': 'keyword2',
-       'move_wizard': 'keyword2',
-       'new': 'keyword2',
-       'new_wizard': 'keyword2',
-       'noResultObj': 'keyword2',
-       'numRows': 'keyword2',
-       'options': 'keyword2',
-       'page': 'keyword2',
-       'pageTree': 'keyword2',
-       'paste': 'keyword2',
-       'perms': 'keyword2',
-       'PIDinRootline': 'keyword2',
-       'PIDupinRootline': 'keyword2',
-       'plugin': 'keyword2',
-       'postform': 'keyword2',
-       'postform_newThread': 'keyword2',
-       'preview': 'keyword2',
-       'publish': 'keyword2',
-       'RADIO': 'keyword2',
-       'renderObj': 'keyword2',
-       'REQ': 'keyword2',
-       'RTE': 'keyword2',
-       'RTE_compliant': 'keyword2',
-       'select': 'keyword2',
-       'setup': 'keyword2',
-       'split': 'keyword2',
-       'stat': 'keyword2',
-       'stat_apache': 'keyword2',
-       'stat_apache_logfile': 'keyword2',
-       'stat_apache_noHost': 'keyword2',
-       'stat_apache_notExtended': 'keyword2',
-       'stat_apache_pagenames': 'keyword2',
-       'stat_excludeBEuserHits': 'keyword2',
-       'stat_excludeIPList': 'keyword2',
-       'stat_mysql': 'keyword2',
-       'stat_titleLen': 'keyword2',
-       'stat_typeNumList': 'keyword2',
-       'stdWrap': 'keyword2',
-       'subparts': 'keyword2',
-       'system': 'keyword2',
-       'temp': 'keyword2',
-       'template': 'keyword2',
-       'treeLevel': 'keyword2',
-       'tsdebug': 'keyword2',
-       'typolink': 'keyword2',
-       'url': 'keyword2',
-       'useragent': 'keyword2',
-       'userFunc': 'keyword2',
-       'version': 'keyword2',
-       'view': 'keyword2',
-       'workOnSubpart': 'keyword2',
-
-       'ACT': 'keyword3',
-       'ACTIFSUB': 'keyword3',
-       'ACTIFSUBRO': 'keyword',
-       'ACTRO': 'keyword3',
-       'all': 'keyword3',
-       'arrowACT': 'keyword3',
-       'arrowNO': 'keyword3',
-       'ascii': 'keyword3',
-       'atLeast': 'keyword3',
-       'atMost': 'keyword3',
-       'BE': 'keyword3',
-       'be_groups': 'keyword3',
-       'be_users': 'keyword3',
-       'BOX': 'keyword3',
-       'browse': 'keyword3',
-       'bullets': 'keyword3',
-       'CUR': 'keyword3',
-       'CURIFSUB': 'keyword3',
-       'CURIFSUBRO': 'keyword3',
-       'CURRO': 'keyword3',
-       'default': 'keyword3',
-       'description': 'keyword3',
-       'directory': 'keyword3',
-       'directReturn': 'keyword3',
-       'div': 'keyword3',
-       'else': 'keyword3',
-       'email': 'keyword3',
-       'end': 'keyword3',
-       'equals': 'keyword3',
-       'external': 'keyword3',
-       'false': 'keyword3',
-       'FE': 'keyword3',
-       'fe_groups': 'keyword3',
-       'fe_users': 'keyword3',
-       'feadmin': 'keyword3',
-       'header': 'keyword3',
-       'html': 'keyword3',
-       'id': 'keyword3',
-       'if': 'keyword3',
-       'ifEmpty': 'keyword3',
-       'IFSUB': 'keyword3',
-       'IFSUBRO': 'keyword3',
-       'image': 'keyword3',
-       'inBranch': 'keyword3',
-       'isFalse': 'keyword3',
-       'isGreaterThan': 'keyword3',
-       'isInList': 'keyword3',
-       'isLessThan': 'keyword3',
-       'isPositive': 'keyword3',
-       'isTrue': 'keyword3',
-       'keyword3': 'keyword3',
-       'language': 'keyword3',
-       'leveltitle': 'keyword3',
-       'list': 'keyword3',
-       'login': 'keyword3',
-       'mailform': 'keyword3',
-       'media': 'keyword3',
-       'menu': 'keyword3',
-       'mod': 'keyword3',
-       'multimedia': 'keyword3',
-       'negate': 'keyword3',
-       'NEW': 'keyword3',
-       'NO': 'keyword3',
-       'none': 'keyword3',
-       'pages': 'keyword3',
-       'pages_language_overlay': 'keyword3',
-       'parseFunc_RTE': 'keyword3',
-       'pid': 'keyword3',
-       'required': 'keyword3',
-       'RO': 'keyword3',
-       'rootline': 'keyword3',
-       'script': 'keyword3',
-       'search': 'keyword3',
-       'shortcut': 'keyword3',
-       'sitemap': 'keyword3',
-       'SPC': 'keyword3',
-       'splash': 'keyword3',
-       'sys_dmail': 'keyword3',
-       'sys_domain': 'keyword3',
-       'sys_filemounts': 'keyword3',
-       'sys_note': 'keyword3',
-       'sys_template': 'keyword3',
-       'tabel': 'keyword3',
-       'text': 'keyword3',
-       'textpic': 'keyword3',
-       'this': 'keyword3',
-       'top': 'keyword3',
-       'true': 'keyword3',
-       'twice': 'keyword3',
-       'uid': 'keyword3',
-       'uniqueGlobal': 'keyword3',
-       'uniqueLocal': 'keyword3',
-       'unsetEmpty': 'keyword3',
-       'updated': 'keyword3',
-       'uploads': 'keyword3',
-       'us': 'keyword3',
-       'user_task': 'keyword3',
-       'USERDEF1': 'keyword3',
-       'USERDEF1RO': 'keyword3',
-       'USERDEF2': 'keyword3',
-       'USERDEF2RO': 'keyword3',
-       'usergroup': 'keyword3',
-       'USR': 'keyword3',
-       'USRRO': 'keyword3',
-       'web_func': 'keyword3',
-       'web_info': 'keyword3',
-       'web_layout': 'keyword3',
-       'web_list': 'keyword3',
-       'web_ts': 'keyword',
-       'xhtml_strict': 'keyword3',
-       'xhtml_trans': 'keyword3',
-       'XY': 'keyword3',
-       'ypMenu': 'keyword3'
-}
-
-var tokenizeTypoScript = function() {
-
-       // Some helper regexp matchers.
-       var isOperatorChar = matcher(/[\+\-\*\&\%\/=<>!\?]/);
-       var isDigit = matcher(/[0-9]/);
-       var isHexDigit = matcher(/[0-9A-Fa-f]/);
-       var isWordChar = matcher(/[\w\$_]/);
-
-       function isWhiteSpace(ch) {
-               // Unfortunately, IE's regexp matcher thinks non-breaking spaces
-               // aren't whitespace. Also, in our scheme newlines are no
-               // whitespace (they are another special case).
-               return ch != "\n" && (ch == nbsp || /\s/.test(ch));
-       }
-
-       // This function produces a MochiKit-style iterator that tokenizes
-       // the output of the given stringstream (see stringstream.js).
-       // Tokens are objects with a type, style, and value property. The
-       // value contains the textual content of the token. Because this may
-       // include trailing whitespace (for efficiency reasons), some
-       // tokens, such a variable names, also have a name property
-       // containing their actual textual value.
-       return function(source) {
-               // Produce a value to return. Automatically skips and includes any
-               // whitespace. The base argument is prepended to the value
-               // property and assigned to the name property -- this is used when
-               // the caller has already extracted the text from the stream
-               // himself.
-               function result(type, style, base) {
-                       // nextWhile(isWhiteSpace); - comment thats line because needed for autocomplete
-                       var value = {
-                               type: type,
-                               style: style,
-                               value: (base ? base + source.get() : source.get())
-                       };
-                       if (base) {
-                               value.name = base;
-                       }
-                       return value;
-               }
-
-               // Advance the text stream over characters for which test returns
-               // true. (The characters that are 'consumed' like this can later
-               // be retrieved by calling source.get()).
-               function nextWhile(test) {
-                       var next;
-                       while ((next = source.peek()) && test(next)) {
-                               source.next();
-                       }
-               }
-
-               // Advance the stream until the given character (not preceded by a
-               // backslash) is encountered (or a newline is found).
-               function nextUntilUnescaped(end) {
-                       var escaped = false;
-                       var next;
-                       while ((next = source.peek()) && next != "\n") {
-                               source.next();
-                               if (next == end && !escaped) {
-                                       break;
-                               }
-                               escaped = next == "\\";
-                       }
-               }
-
-               function readHexNumber() {
-                       source.next();
-                       // skip the 'x'
-                       nextWhile(isHexDigit);
-                       return result("number", "atom");
-               }
-
-               function readNumber() {
-                       nextWhile(isDigit);
-                       return result("number", "atom");
-               }
-
-               // Read a word, look it up in keywords. If not found, it is a
-               // variable, otherwise it is a keyword of the type found.
-               function readWord() {
-                       nextWhile(isWordChar);
-                       var word = source.get();
-                       var known = typoscriptWords.hasOwnProperty(word) && {
-                               type: 'keyword',
-                               style: typoscriptWords[word]
-                       };
-                       return known ?
-                               result(known.type, known.style, word) :
-                               result("variable", "other", word);
-               }
-
-               function readRegexp() {
-                       nextUntilUnescaped("/");
-                       nextWhile(matcher(/[gi]/));
-                       return result("regexp", "string");
-               }
-
-               // Mutli-line comments are tricky. We want to return the newlines
-               // embedded in them as regular newline tokens, and then continue
-               // returning a comment token for every line of the comment. So
-               // some state has to be saved (inComment) to indicate whether we
-               // are inside a /* */ sequence.
-               function readMultilineComment(start) {
-                       this.inComment = true;
-                       var maybeEnd = (start == "*");
-                       while (true) {
-                               var next = source.peek();
-                               if (next == "\n") {
-                                       break;
-                               }
-                               source.next();
-                               if (next == "/" && maybeEnd) {
-                                       this.inComment = false;
-                                       break;
-                               }
-                               maybeEnd = (next == "*");
-                       }
-
-                       return result("comment", "ts-comment");
-               }
-
-               // Fetch the next token. Dispatches on first character in the
-               // stream, or first two characters when the first is a slash. The
-               // || things are a silly trick to keep simple cases on a single
-               // line.
-               function next() {
-                       var token = null;
-                       var ch = source.next();
-                       if (ch == "\n") {
-                               token = {
-                                       type: "newline",
-                                       style: "whitespace",
-                                       value: source.get()
-                               };
-                               this.inValue = false;
-
-                       } else if (!this.inValue && this.inComment) {
-                               token = readMultilineComment.call(this, ch);
-                       
-                       /*
-                       } else if (this.inValue) {
-                               token = nextUntilUnescaped(null) || {
-                                       type: "value",
-                                       style: "ts-value",
-                                       value: source.get()
-                               };
-                               this.inValue = false;
-                       */
-
-                       } else if (isWhiteSpace(ch)) {
-                               token = nextWhile(isWhiteSpace) || result("whitespace", "whitespace");
-
-                       } else if (!this.inValue && (ch == "\"" || ch == "'")) {
-                               token = nextUntilUnescaped(ch) || result("string", "string");
-
-                       } else if (
-                          ( ch == "<" || 
-                                  ch == ">" ||
-                                ( ch == "=" 
-                                  && source.peek() != "<" 
-                                )
-                          )
-                          && source.peek() != "\n" ) { // there must be some value behind the operator!
-                               this.inValue = true;
-                               token = result(ch, "ts-operator");
-
-                       } else if (!this.inValue && ch == "[") {
-                               token = nextUntilUnescaped("]") || result("condition", "ts-condition");
-
-                       // with punctuation, the type of the token is the symbol itself
-                       } else if (!this.inValue && /[\[\]\(\),;\:\.\<\>\=]/.test(ch)) {
-                               token = result(ch, "ts-operator");
-
-                       } else if (!this.inValue && (ch == "{" || ch == "}")) {
-                               token = result(ch, "ts-operator curly-bracket");
-
-                       } else if (!this.inValue && ch == "0" && (source.peek() == "x" || source.peek() == "X")) {
-                               token = readHexNumber();
-
-                       } else if (!this.inValue && isDigit(ch)) {
-                               token = readNumber();
-
-                       } else if (!this.inValue && ch == "/") {
-                               next = source.peek();
-
-                               if (next == "*") {
-                                       token = readMultilineComment.call(this, ch);
-
-                               } else if (next == "/") {
-                                       token = nextUntilUnescaped(null) || result("comment", "ts-comment");
-
-                               } else if (this.regexp) {
-                                       token = readRegexp();
-
-                               } else {
-                                       token = nextWhile(isOperatorChar) || result("operator", "ts-operator");
-                               }
-
-                       } else if (!this.inValue && ch == "#") {
-                               token = nextUntilUnescaped(null) || result("comment", "ts-comment");
-
-                       } else if (!this.inValue && isOperatorChar(ch)) {
-                               token = nextWhile(isOperatorChar) || result("operator", "ts-operator");
-
-                       } else {
-                               token = readWord();
-                               if (this.inValue) {
-                                       token.style += ' ts-value';
-                               }
-                       }
-
-                       // JavaScript's syntax rules for when a slash might be the start
-                       // of a regexp and when it is just a division operator are kind
-                       // of non-obvious. This decides, based on the current token,
-                       // whether the next token could be a regular expression.
-                       if (token.style != "whitespace" && token != "comment") {
-                               this.regexp = token.type == "operator" || token.type == "keyword c" || token.type.match(/[\[{}\(,;:]/);
-                       }
-                       return token;
-               }
-
-               // Wrap it in an iterator. The state (regexp and inComment) is
-               // exposed because a parser will need to save it when making a
-               // copy of its state.
-               return {
-                       next: next,
-                       regexp: true,
-                       inComment: false,
-                       inValue: false
-               };
-       }
-} ();
diff --git a/typo3/sysext/t3editor/jslib/codemirror/undo.js b/typo3/sysext/t3editor/jslib/codemirror/undo.js
deleted file mode 100644 (file)
index f7990ee..0000000
+++ /dev/null
@@ -1,388 +0,0 @@
-/**
- * Storage and control for undo information within a CodeMirror
- * editor. 'Why on earth is such a complicated mess required for
- * that?', I hear you ask. The goal, in implementing this, was to make
- * the complexity of storing and reverting undo information depend
- * only on the size of the edited or restored content, not on the size
- * of the whole document. This makes it necessary to use a kind of
- * 'diff' system, which, when applied to a DOM tree, causes some
- * complexity and hackery.
- *
- * In short, the editor 'touches' BR elements as it parses them, and
- * the History stores these. When nothing is touched in commitDelay
- * milliseconds, the changes are committed: It goes over all touched
- * nodes, throws out the ones that did not change since last commit or
- * are no longer in the document, and assembles the rest into zero or
- * more 'chains' -- arrays of adjacent lines. Links back to these
- * chains are added to the BR nodes, while the chain that previously
- * spanned these nodes is added to the undo history. Undoing a change
- * means taking such a chain off the undo history, restoring its
- * content (text is saved per line) and linking it back into the
- * document.
- */
-
-// A history object needs to know about the DOM container holding the
-// document, the maximum amount of undo levels it should store, the
-// delay (of no input) after which it commits a set of changes, and,
-// unfortunately, the 'parent' window -- a window that is not in
-// designMode, and on which setTimeout works in every browser.
-function History(container, maxDepth, commitDelay, editor, onChange) {
-  this.container = container;
-  this.maxDepth = maxDepth; this.commitDelay = commitDelay;
-  this.editor = editor; this.parent = editor.parent;
-  this.onChange = onChange;
-  // This line object represents the initial, empty editor.
-  var initial = {text: "", from: null, to: null};
-  // As the borders between lines are represented by BR elements, the
-  // start of the first line and the end of the last one are
-  // represented by null. Since you can not store any properties
-  // (links to line objects) in null, these properties are used in
-  // those cases.
-  this.first = initial; this.last = initial;
-  // Similarly, a 'historyTouched' property is added to the BR in
-  // front of lines that have already been touched, and 'firstTouched'
-  // is used for the first line.
-  this.firstTouched = false;
-  // History is the set of committed changes, touched is the set of
-  // nodes touched since the last commit.
-  this.history = []; this.redoHistory = []; this.touched = [];
-}
-
-History.prototype = {
-  // Schedule a commit (if no other touches come in for commitDelay
-  // milliseconds).
-  scheduleCommit: function() {
-    this.parent.clearTimeout(this.commitTimeout);
-    this.commitTimeout = this.parent.setTimeout(method(this, "tryCommit"), this.commitDelay);
-  },
-
-  // Mark a node as touched. Null is a valid argument.
-  touch: function(node) {
-    this.setTouched(node);
-    this.scheduleCommit();
-  },
-
-  // Undo the last change.
-  undo: function() {
-    // Make sure pending changes have been committed.
-    this.commit();
-
-    if (this.history.length) {
-      // Take the top diff from the history, apply it, and store its
-      // shadow in the redo history.
-      this.redoHistory.push(this.updateTo(this.history.pop(), "applyChain"));
-      if (this.onChange) this.onChange();
-    }
-  },
-
-  // Redo the last undone change.
-  redo: function() {
-    this.commit();
-    if (this.redoHistory.length) {
-      // The inverse of undo, basically.
-      this.addUndoLevel(this.updateTo(this.redoHistory.pop(), "applyChain"));
-      if (this.onChange) this.onChange();
-    }
-  },
-
-  // Push a changeset into the document.
-  push: function(from, to, lines) {
-    var chain = [];
-    for (var i = 0; i < lines.length; i++) {
-      var end = (i == lines.length - 1) ? to : this.container.ownerDocument.createElement("BR");
-      chain.push({from: from, to: end, text: lines[i]});
-      from = end;
-    }
-    this.pushChains([chain], from == null && to == null);
-  },
-
-  pushChains: function(chains, doNotHighlight) {
-    this.commit(doNotHighlight);
-    this.addUndoLevel(this.updateTo(chains, "applyChain"));
-    this.redoHistory = [];
-  },
-
-  // Clear the undo history, make the current document the start
-  // position.
-  reset: function() {
-    this.history = []; this.redoHistory = [];
-  },
-
-  textAfter: function(br) {
-    return this.after(br).text;
-  },
-
-  nodeAfter: function(br) {
-    return this.after(br).to;
-  },
-
-  nodeBefore: function(br) {
-    return this.before(br).from;
-  },
-
-  // Commit unless there are pending dirty nodes.
-  tryCommit: function() {
-    if (this.editor.highlightDirty()) this.commit();
-    else this.scheduleCommit();
-  },
-
-  // Check whether the touched nodes hold any changes, if so, commit
-  // them.
-  commit: function(doNotHighlight) {
-    this.parent.clearTimeout(this.commitTimeout);
-    // Make sure there are no pending dirty nodes.
-    if (!doNotHighlight) this.editor.highlightDirty(true);
-    // Build set of chains.
-    var chains = this.touchedChains(), self = this;
-
-    if (chains.length) {
-      this.addUndoLevel(this.updateTo(chains, "linkChain"));
-      this.redoHistory = [];
-      if (this.onChange) this.onChange();
-    }
-  },
-
-  // [ end of public interface ]
-
-  // Update the document with a given set of chains, return its
-  // shadow. updateFunc should be "applyChain" or "linkChain". In the
-  // second case, the chains are taken to correspond the the current
-  // document, and only the state of the line data is updated. In the
-  // first case, the content of the chains is also pushed iinto the
-  // document.
-  updateTo: function(chains, updateFunc) {
-    var shadows = [], dirty = [];
-    for (var i = 0; i < chains.length; i++) {
-      shadows.push(this.shadowChain(chains[i]));
-      dirty.push(this[updateFunc](chains[i]));
-    }
-    if (updateFunc == "applyChain")
-      this.notifyDirty(dirty);
-    return shadows;
-  },
-
-  // Notify the editor that some nodes have changed.
-  notifyDirty: function(nodes) {
-    forEach(nodes, method(this.editor, "addDirtyNode"))
-    this.editor.scheduleHighlight();
-  },
-
-  // Link a chain into the DOM nodes (or the first/last links for null
-  // nodes).
-  linkChain: function(chain) {
-    for (var i = 0; i < chain.length; i++) {
-      var line = chain[i];
-      if (line.from) line.from.historyAfter = line;
-      else this.first = line;
-      if (line.to) line.to.historyBefore = line;
-      else this.last = line;
-    }
-  },
-
-  // Get the line object after/before a given node.
-  after: function(node) {
-    return node ? node.historyAfter : this.first;
-  },
-  before: function(node) {
-    return node ? node.historyBefore : this.last;
-  },
-
-  // Mark a node as touched if it has not already been marked.
-  setTouched: function(node) {
-    if (node) {
-      if (!node.historyTouched) {
-        this.touched.push(node);
-        node.historyTouched = true;
-      }
-    }
-    else {
-      this.firstTouched = true;
-    }
-  },
-
-  // Store a new set of undo info, throw away info if there is more of
-  // it than allowed.
-  addUndoLevel: function(diffs) {
-    this.history.push(diffs);
-    if (this.history.length > this.maxDepth)
-      this.history.shift();
-  },
-
-  // Build chains from a set of touched nodes.
-  touchedChains: function() {
-    var self = this;
-    // Compare two strings, treating nbsps as spaces.
-    function compareText(a, b) {
-      return a.replace(/\u00a0/g, " ") == b.replace(/\u00a0/g, " ");
-    }
-
-    // The temp system is a crummy hack to speed up determining
-    // whether a (currently touched) node has a line object associated
-    // with it. nullTemp is used to store the object for the first
-    // line, other nodes get it stored in their historyTemp property.
-    var nullTemp = null;
-    function temp(node) {return node ? node.historyTemp : nullTemp;}
-    function setTemp(node, line) {
-      if (node) node.historyTemp = line;
-      else nullTemp = line;
-    }
-
-    function buildLine(node) {
-      var text = [];
-      for (var cur = node ? node.nextSibling : self.container.firstChild;
-           cur && cur.nodeName != "BR"; cur = cur.nextSibling)
-        if (cur.currentText) text.push(cur.currentText);
-      return {from: node, to: cur, text: text.join("")};
-    }
-
-    // Filter out unchanged lines and nodes that are no longer in the
-    // document. Build up line objects for remaining nodes.
-    var lines = [];
-    if (self.firstTouched) self.touched.push(null);
-    forEach(self.touched, function(node) {
-      if (node && node.parentNode != self.container) return;
-
-      if (node) node.historyTouched = false;
-      else self.firstTouched = false;
-
-      var line = buildLine(node), shadow = self.after(node);
-      if (!shadow || !compareText(shadow.text, line.text) || shadow.to != line.to) {
-        lines.push(line);
-        setTemp(node, line);
-      }
-    });
-
-    // Get the BR element after/before the given node.
-    function nextBR(node, dir) {
-      var link = dir + "Sibling", search = node[link];
-      while (search && search.nodeName != "BR")
-        search = search[link];
-      return search;
-    }
-
-    // Assemble line objects into chains by scanning the DOM tree
-    // around them.
-    var chains = []; self.touched = [];
-    forEach(lines, function(line) {
-      // Note that this makes the loop skip line objects that have
-      // been pulled into chains by lines before them.
-      if (!temp(line.from)) return;
-
-      var chain = [], curNode = line.from, safe = true;
-      // Put any line objects (referred to by temp info) before this
-      // one on the front of the array.
-      while (true) {
-        var curLine = temp(curNode);
-        if (!curLine) {
-          if (safe) break;
-          else curLine = buildLine(curNode);
-        }
-        chain.unshift(curLine);
-        setTemp(curNode, null);
-        if (!curNode) break;
-        safe = self.after(curNode);
-        curNode = nextBR(curNode, "previous");
-      }
-      curNode = line.to; safe = self.before(line.from);
-      // Add lines after this one at end of array.
-      while (true) {
-        if (!curNode) break;
-        var curLine = temp(curNode);
-        if (!curLine) {
-          if (safe) break;
-          else curLine = buildLine(curNode);
-        }
-        chain.push(curLine);
-        setTemp(curNode, null);
-        safe = self.before(curNode);
-        curNode = nextBR(curNode, "next");
-      }
-      chains.push(chain);
-    });
-
-    return chains;
-  },
-
-  // Find the 'shadow' of a given chain by following the links in the
-  // DOM nodes at its start and end.
-  shadowChain: function(chain) {
-    var shadows = [], next = this.after(chain[0].from), end = chain[chain.length - 1].to;
-    while (true) {
-      shadows.push(next);
-      var nextNode = next.to;
-      if (!nextNode || nextNode == end)
-        break;
-      else
-        next = nextNode.historyAfter || this.before(end);
-      // (The this.before(end) is a hack -- FF sometimes removes
-      // properties from BR nodes, in which case the best we can hope
-      // for is to not break.)
-    }
-    return shadows;
-  },
-
-  // Update the DOM tree to contain the lines specified in a given
-  // chain, link this chain into the DOM nodes.
-  applyChain: function(chain) {
-    // Some attempt is made to prevent the cursor from jumping
-    // randomly when an undo or redo happens. It still behaves a bit
-    // strange sometimes.
-    var cursor = select.cursorPos(this.container, false), self = this;
-
-    // Remove all nodes in the DOM tree between from and to (null for
-    // start/end of container).
-    function removeRange(from, to) {
-      var pos = from ? from.nextSibling : self.container.firstChild;
-      while (pos != to) {
-        var temp = pos.nextSibling;
-        removeElement(pos);
-        pos = temp;
-      }
-    }
-
-    var start = chain[0].from, end = chain[chain.length - 1].to;
-    // Clear the space where this change has to be made.
-    removeRange(start, end);
-
-    // Build a function that will insert nodes before the end node of
-    // this chain.
-    var insert = end ?
-      function(node) {self.container.insertBefore(node, end);}
-    : function(node) {self.container.appendChild(node);};
-
-    // Insert the content specified by the chain into the DOM tree.
-    for (var i = 0; i < chain.length; i++) {
-      var line = chain[i];
-      // The start and end of the space are already correct, but BR
-      // tags inside it have to be put back.
-      if (i > 0)
-        insert(line.from);
-      // Add the text.
-      var node = makePartSpan(splitSpaces(line.text), this.container.ownerDocument);
-      insert(node);
-      // See if the cursor was on this line. Put it back, adjusting
-      // for changed line length, if it was.
-      if (cursor && cursor.node == line.from) {
-        var cursordiff = 0;
-        var prev = this.after(line.from);
-        if (prev && i == chain.length - 1) {
-          // Only adjust if the cursor is after the unchanged part of
-          // the line.
-          for (var match = 0; match < cursor.offset &&
-               line.text.charAt(match) == prev.text.charAt(match); match++);
-          if (cursor.offset > match)
-            cursordiff = line.text.length - prev.text.length;
-        }
-        select.setCursorPos(this.container, {node: line.from, offset: Math.max(0, cursor.offset + cursordiff)});
-      }
-      // Cursor was in removed line, this is last new line.
-      else if (cursor && (i == chain.length - 1) && cursor.node && cursor.node.parentNode != this.container) {
-        select.setCursorPos(this.container, {node: line.from, offset: line.text.length});
-      }
-    }
-
-    // Anchor the chain in the DOM tree.
-    this.linkChain(chain);
-    return start;
-  }
-};
diff --git a/typo3/sysext/t3editor/jslib/codemirror/util.js b/typo3/sysext/t3editor/jslib/codemirror/util.js
deleted file mode 100644 (file)
index ba2e3d4..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/* A few useful utility functions. */
-
-// Capture a method on an object.
-function method(obj, name) {
-  return function() {obj[name].apply(obj, arguments);};
-}
-
-// The value used to signal the end of a sequence in iterators.
-var StopIteration = {toString: function() {return "StopIteration"}};
-
-// Checks whether the argument is an iterator or a regular sequence,
-// turns it into an iterator.
-function iter(seq) {
-  var i = 0;
-  if (seq.next) return seq;
-  else return {
-    next: function() {
-      if (i >= seq.length) throw StopIteration;
-      else return seq[i++];
-    }
-  };
-}
-
-// Apply a function to each element in a sequence.
-function forEach(iter, f) {
-  if (iter.next) {
-    try {while (true) f(iter.next());}
-    catch (e) {if (e != StopIteration) throw e;}
-  }
-  else {
-    for (var i = 0; i < iter.length; i++)
-      f(iter[i]);
-  }
-}
-
-// Map a function over a sequence, producing an array of results.
-function map(iter, f) {
-  var accum = [];
-  forEach(iter, function(val) {accum.push(f(val));});
-  return accum;
-}
-
-// Create a predicate function that tests a string againsts a given
-// regular expression.
-function matcher(regexp){
-  return function(value){return regexp.test(value);};
-}
-
-// Test whether a DOM node has a certain CSS class. Much faster than
-// the MochiKit equivalent, for some reason.
-function hasClass(element, className){
-  var classes = element.className;
-  return classes && new RegExp("(^| )" + className + "($| )").test(classes);
-}
-
-// Insert a DOM node after another node.
-function insertAfter(newNode, oldNode) {
-  var parent = oldNode.parentNode;
-  parent.insertBefore(newNode, oldNode.nextSibling);
-  return newNode;
-}
-
-function removeElement(node) {
-  if (node.parentNode)
-    node.parentNode.removeChild(node);
-}
-
-function clearElement(node) {
-  while (node.firstChild)
-    node.removeChild(node.firstChild);
-}
-
-// Check whether a node is contained in another one.
-function isAncestor(node, child) {
-  while (child = child.parentNode) {
-    if (node == child)
-      return true;
-  }
-  return false;
-}
-
-// The non-breaking space character.
-var nbsp = "\u00a0";
-var matching = {"{": "}", "[": "]", "(": ")",
-                "}": "{", "]": "[", ")": "("};
-
-// Standardize a few unportable event properties.
-function normalizeEvent(event) {
-  if (!event.stopPropagation) {
-    event.stopPropagation = function() {this.cancelBubble = true;};
-    event.preventDefault = function() {this.returnValue = false;};
-  }
-  if (!event.stop) {
-    event.stop = function() {
-      this.stopPropagation();
-      this.preventDefault();
-    };
-  }
-
-  if (event.type == "keypress") {
-    if (event.charCode === 0 || event.charCode == undefined)
-      event.code = event.keyCode;
-    else
-      event.code = event.charCode;
-    event.character = String.fromCharCode(event.code);
-  }
-  return event;
-}
-
-// Portably register event handlers.
-function addEventHandler(node, type, handler, removeFunc) {
-  function wrapHandler(event) {
-    handler(normalizeEvent(event || window.event));
-  }
-  if (typeof node.addEventListener == "function") {
-    node.addEventListener(type, wrapHandler, false);
-    if (removeFunc) return function() {node.removeEventListener(type, wrapHandler, false);};
-  }
-  else {
-    node.attachEvent("on" + type, wrapHandler);
-    if (removeFunc) return function() {node.detachEvent("on" + type, wrapHandler);};
-  }
-}
diff --git a/typo3/sysext/t3editor/jslib/t3editor.js b/typo3/sysext/t3editor/jslib/t3editor.js
deleted file mode 100755 (executable)
index 7e15f6a..0000000
+++ /dev/null
@@ -1,405 +0,0 @@
-/***************************************************************
-*  Copyright notice
-*
-*  (c) 2007-2009 Tobias Liebig <mail_typo3@etobi.de>
-*  All rights reserved
-*
-*  This script is part of the TYPO3 project. The TYPO3 project is
-*  free software; you can redistribute it and/or modify
-*  it under the terms of the GNU General Public License as published by
-*  the Free Software Foundation; either version 2 of the License, or
-*  (at your option) any later version.
-*
-*  The GNU General Public License can be found at
-*  http://www.gnu.org/copyleft/gpl.html.
-*  A copy is found in the textfile GPL.txt and important notices to the license
-*  from the author is found in LICENSE.txt distributed with these scripts.
-*
-*
-*  This script is distributed in the hope that it will be useful,
-*  but WITHOUT ANY WARRANTY; without even the implied warranty of
-*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-*  GNU General Public License for more details.
-*
-*  This copyright notice MUST APPEAR in all copies of the script!
-***************************************************************/
-/* t3editor.js uses the Codemirror editor.
- */
-
-
-// collection of all t3editor instances on the current page
-var t3e_instances = {};
-
-// path to the editor ext dir
-// can be overwritten in class.tx_t3editor.php
-var PATH_t3e = "../../../sysext/t3editor/";
-