Cleanup: Fixed svn:eol-style
authorOliver Hader <oliver.hader@typo3.org>
Mon, 29 Nov 2010 14:44:51 +0000 (14:44 +0000)
committerOliver Hader <oliver.hader@typo3.org>
Mon, 29 Nov 2010 14:44:51 +0000 (14:44 +0000)
git-svn-id: https://svn.typo3.org/TYPO3v4/Core/trunk@9674 709f56b5-9817-0410-a4d7-c38de5d9e867

t3lib/js/extjs/ux/Ext.app.SearchField.js
t3lib/js/extjs/ux/Ext.grid.RowExpander.js
t3lib/js/extjs/ux/Ext.ux.FitToParent.js
t3lib/tceforms/class.t3lib_tceforms_flexforms.php
tests/t3lib/tree/t3lib_tree_nodeTest.php
typo3/contrib/codemirror/contrib/groovy/index.html
typo3/sysext/em/classes/class.tx_em_api.php
typo3/sysext/rtehtmlarea/templates/rtehtmlarea_pageheader_frontend.html
typo3/sysext/t3editor/classes/class.tx_t3editor_hooks_fileedit.php
typo3/sysext/t3editor/res/jslib/parse_typoscript/parsetyposcript.js
typo3/sysext/t3editor/res/jslib/parse_typoscript/tokenizetyposcript.js

index 0130147..03784b2 100644 (file)
@@ -1,53 +1,53 @@
-/*\r
- * Ext JS Library 2.2.1\r
- * Copyright(c) 2006-2009, Ext JS, LLC.\r
- * licensing@extjs.com\r
- *\r
- * http://extjs.com/license\r
- */\r
-\r
-Ext.app.SearchField = Ext.extend(Ext.form.TwinTriggerField, {\r
-       initComponent : function() {\r
-               Ext.app.SearchField.superclass.initComponent.call(this);\r
-               this.on('specialkey', function(f, e) {\r
-                       if (e.getKey() == e.ENTER) {\r
-                               this.onTrigger2Click();\r
-                       }\r
-               }, this);\r
-       },\r
-\r
-       validationEvent: false,\r
-       validateOnBlur: false,\r
-       trigger1Class: 'x-form-clear-trigger',\r
-       trigger2Class: 'x-form-search-trigger',\r
-       hideTrigger1: true,\r
-       width: 180,\r
-       hasSearch : false,\r
-       paramName : 'filterTxt',\r
-\r
-       onTrigger1Click : function() {\r
-               if (this.hasSearch) {\r
-                       this.el.dom.value = '';\r
-                       var o = {start: 0};\r
-                       this.store.baseParams = this.store.baseParams || {};\r
-                       this.store.baseParams[this.paramName] = '';\r
-                       this.store.reload({params:o});\r
-                       this.triggers[0].hide();\r
-                       this.hasSearch = false;\r
-               }\r
-       },\r
-\r
-       onTrigger2Click : function() {\r
-               var v = this.getRawValue();\r
-               if (v.length < 1) {\r
-                       this.onTrigger1Click();\r
-                       return;\r
-               }\r
-               var o = {start: 0};\r
-               this.store.baseParams = this.store.baseParams || {};\r
-               this.store.baseParams[this.paramName] = v;\r
-               this.store.reload({params:o});\r
-               this.hasSearch = true;\r
-               this.triggers[0].show();\r
-       }\r
+/*
+ * Ext JS Library 2.2.1
+ * Copyright(c) 2006-2009, Ext JS, LLC.
+ * licensing@extjs.com
+ *
+ * http://extjs.com/license
+ */
+
+Ext.app.SearchField = Ext.extend(Ext.form.TwinTriggerField, {
+       initComponent : function() {
+               Ext.app.SearchField.superclass.initComponent.call(this);
+               this.on('specialkey', function(f, e) {
+                       if (e.getKey() == e.ENTER) {
+                               this.onTrigger2Click();
+                       }
+               }, this);
+       },
+
+       validationEvent: false,
+       validateOnBlur: false,
+       trigger1Class: 'x-form-clear-trigger',
+       trigger2Class: 'x-form-search-trigger',
+       hideTrigger1: true,
+       width: 180,
+       hasSearch : false,
+       paramName : 'filterTxt',
+
+       onTrigger1Click : function() {
+               if (this.hasSearch) {
+                       this.el.dom.value = '';
+                       var o = {start: 0};
+                       this.store.baseParams = this.store.baseParams || {};
+                       this.store.baseParams[this.paramName] = '';
+                       this.store.reload({params:o});
+                       this.triggers[0].hide();
+                       this.hasSearch = false;
+               }
+       },
+
+       onTrigger2Click : function() {
+               var v = this.getRawValue();
+               if (v.length < 1) {
+                       this.onTrigger1Click();
+                       return;
+               }
+               var o = {start: 0};
+               this.store.baseParams = this.store.baseParams || {};
+               this.store.baseParams[this.paramName] = v;
+               this.store.reload({params:o});
+               this.hasSearch = true;
+               this.triggers[0].show();
+       }
 });
\ No newline at end of file
index 673d692..6ca6ac8 100644 (file)
-/*\r
- * Ext JS Library 2.0\r
- * Copyright(c) 2006-2007, Ext JS, LLC.\r
- * licensing@extjs.com\r
- *\r
- * http://extjs.com/license\r
- *\r
- * MODIFIED: SGB [12.12.07]\r
- * Added support for a new config option, remoteDataMethod,\r
- * including getter and setter functions, and minor mods\r
- * to the beforeExpand and expandRow functions\r
- */\r
-\r
-Ext.grid.RowExpander = function(config) {\r
-       Ext.apply(this, config);\r
-       Ext.grid.RowExpander.superclass.constructor.call(this);\r
-\r
-       if (this.tpl) {\r
-               if (typeof this.tpl == 'string') {\r
-                       this.tpl = new Ext.Template(this.tpl);\r
-               }\r
-               this.tpl.compile();\r
-       }\r
-\r
-       this.state = {};\r
-       this.bodyContent = {};\r
-\r
-       this.addEvents({\r
-               beforeexpand : true,\r
-               expand: true,\r
-               beforecollapse: true,\r
-               collapse: true\r
-       });\r
-};\r
-\r
-Ext.extend(Ext.grid.RowExpander, Ext.util.Observable, {\r
-       header: "",\r
-       width: 20,\r
-       sortable: false,\r
-       fixed:true,\r
-       dataIndex: '',\r
-       id: 'expander',\r
-       lazyRender : true,\r
-       enableCaching: true,\r
-\r
-       getRowClass : function(record, rowIndex, p, ds) {\r
-               p.cols = p.cols-1;\r
-               var content = this.bodyContent[record.id];\r
-               if (!content && !this.lazyRender) {\r
-                       content = this.getBodyContent(record, rowIndex);\r
-               }\r
-               if (content) {\r
-                       p.body = content;\r
-               }\r
-               return this.state[record.id] ? 'x-grid3-row-expanded' : 'x-grid3-row-collapsed';\r
-       },\r
-\r
-       init : function(grid) {\r
-               this.grid = grid;\r
-\r
-               var view = grid.getView();\r
-               view.getRowClass = this.getRowClass.createDelegate(this);\r
-\r
-               view.enableRowBody = true;\r
-\r
-               grid.on('render', function() {\r
-                       view.mainBody.on('mousedown', this.onMouseDown, this);\r
-               }, this);\r
-       },\r
-\r
-       getBodyContent : function(record, index) {\r
-               if (!this.enableCaching) {\r
-                       return this.tpl.apply(record.data);\r
-               }\r
-               var content = this.bodyContent[record.id];\r
-               if (!content) {\r
-                       content = this.tpl.apply(record.data);\r
-                       this.bodyContent[record.id] = content;\r
-               }\r
-               return content;\r
-       },\r
-       // Setter and Getter methods for the remoteDataMethod property\r
-       setRemoteDataMethod : function (fn) {\r
-               this.remoteDataMethod = fn;\r
-       },\r
-\r
-       getRemoteDataMethod : function (record, index) {\r
-               if (!this.remoteDataMethod) {\r
-                       return;\r
-               }\r
-                       return this.remoteDataMethod.call(this,record,index);\r
-       },\r
-\r
-       onMouseDown : function(e, t) {\r
-               if (t.className == 'x-grid3-row-expander') {\r
-                       e.stopEvent();\r
-                       var row = e.getTarget('.x-grid3-row');\r
-                       this.toggleRow(row);\r
-               }\r
-       },\r
-\r
-       renderer : function(v, p, record) {\r
-               p.cellAttr = 'rowspan="2"';\r
-               return '<div class="x-grid3-row-expander">&#160;</div>';\r
-       },\r
-\r
-       beforeExpand : function(record, body, rowIndex) {\r
-               if (this.fireEvent('beforexpand', this, record, body, rowIndex) !== false) {\r
-                       // If remoteDataMethod is defined then we'll need a div, with a unique ID,\r
-                       //  to place the content\r
-                       if (this.remoteDataMethod) {\r
-                               this.tpl = new Ext.Template("<div id=\"remData" + rowIndex + "\" class=\"rem-data-expand\"><\div>");\r
-                       }\r
-                       if (this.tpl && this.lazyRender) {\r
-                               body.innerHTML = this.getBodyContent(record, rowIndex);\r
-                       }\r
-\r
-                       return true;\r
-               }else{\r
-                       return false;\r
-               }\r
-       },\r
-\r
-       toggleRow : function(row) {\r
-               if (typeof row == 'number') {\r
-                       row = this.grid.view.getRow(row);\r
-               }\r
-               this[Ext.fly(row).hasClass('x-grid3-row-collapsed') ? 'expandRow' : 'collapseRow'](row);\r
-       },\r
-\r
-       expandRow : function(row) {\r
-               if (typeof row == 'number') {\r
-                       row = this.grid.view.getRow(row);\r
-               }\r
-               var record = this.grid.store.getAt(row.rowIndex);\r
-               var body = Ext.DomQuery.selectNode('tr:nth(2) div.x-grid3-row-body', row);\r
-               if (this.beforeExpand(record, body, row.rowIndex)) {\r
-                       this.state[record.id] = true;\r
-                       Ext.fly(row).replaceClass('x-grid3-row-collapsed', 'x-grid3-row-expanded');\r
-                       if (this.fireEvent('expand', this, record, body, row.rowIndex) !== false) {\r
-                               //  If the expand event is successful then get the remoteDataMethod\r
-                               this.getRemoteDataMethod(record,row.rowIndex);\r
-                       }\r
-               }\r
-       },\r
-\r
-       collapseRow : function(row) {\r
-               if (typeof row == 'number') {\r
-                       row = this.grid.view.getRow(row);\r
-               }\r
-               var record = this.grid.store.getAt(row.rowIndex);\r
-               var body = Ext.fly(row).child('tr:nth(1) div.x-grid3-row-body', true);\r
-               if (this.fireEvent('beforcollapse', this, record, body, row.rowIndex) !== false) {\r
-                       this.state[record.id] = false;\r
-                       Ext.fly(row).replaceClass('x-grid3-row-expanded', 'x-grid3-row-collapsed');\r
-                       this.fireEvent('collapse', this, record, body, row.rowIndex);\r
-               }\r
-       }\r
-});\r
+/*
+ * Ext JS Library 2.0
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ * licensing@extjs.com
+ *
+ * http://extjs.com/license
+ *
+ * MODIFIED: SGB [12.12.07]
+ * Added support for a new config option, remoteDataMethod,
+ * including getter and setter functions, and minor mods
+ * to the beforeExpand and expandRow functions
+ */
+
+Ext.grid.RowExpander = function(config) {
+       Ext.apply(this, config);
+       Ext.grid.RowExpander.superclass.constructor.call(this);
+
+       if (this.tpl) {
+               if (typeof this.tpl == 'string') {
+                       this.tpl = new Ext.Template(this.tpl);
+               }
+               this.tpl.compile();
+       }
+
+       this.state = {};
+       this.bodyContent = {};
+
+       this.addEvents({
+               beforeexpand : true,
+               expand: true,
+               beforecollapse: true,
+               collapse: true
+       });
+};
+
+Ext.extend(Ext.grid.RowExpander, Ext.util.Observable, {
+       header: "",
+       width: 20,
+       sortable: false,
+       fixed:true,
+       dataIndex: '',
+       id: 'expander',
+       lazyRender : true,
+       enableCaching: true,
+
+       getRowClass : function(record, rowIndex, p, ds) {
+               p.cols = p.cols-1;
+               var content = this.bodyContent[record.id];
+               if (!content && !this.lazyRender) {
+                       content = this.getBodyContent(record, rowIndex);
+               }
+               if (content) {
+                       p.body = content;
+               }
+               return this.state[record.id] ? 'x-grid3-row-expanded' : 'x-grid3-row-collapsed';
+       },
+
+       init : function(grid) {
+               this.grid = grid;
+
+               var view = grid.getView();
+               view.getRowClass = this.getRowClass.createDelegate(this);
+
+               view.enableRowBody = true;
+
+               grid.on('render', function() {
+                       view.mainBody.on('mousedown', this.onMouseDown, this);
+               }, this);
+       },
+
+       getBodyContent : function(record, index) {
+               if (!this.enableCaching) {
+                       return this.tpl.apply(record.data);
+               }
+               var content = this.bodyContent[record.id];
+               if (!content) {
+                       content = this.tpl.apply(record.data);
+                       this.bodyContent[record.id] = content;
+               }
+               return content;
+       },
+       // Setter and Getter methods for the remoteDataMethod property
+       setRemoteDataMethod : function (fn) {
+               this.remoteDataMethod = fn;
+       },
+
+       getRemoteDataMethod : function (record, index) {
+               if (!this.remoteDataMethod) {
+                       return;
+               }
+                       return this.remoteDataMethod.call(this,record,index);
+       },
+
+       onMouseDown : function(e, t) {
+               if (t.className == 'x-grid3-row-expander') {
+                       e.stopEvent();
+                       var row = e.getTarget('.x-grid3-row');
+                       this.toggleRow(row);
+               }
+       },
+
+       renderer : function(v, p, record) {
+               p.cellAttr = 'rowspan="2"';
+               return '<div class="x-grid3-row-expander">&#160;</div>';
+       },
+
+       beforeExpand : function(record, body, rowIndex) {
+               if (this.fireEvent('beforexpand', this, record, body, rowIndex) !== false) {
+                       // If remoteDataMethod is defined then we'll need a div, with a unique ID,
+                       //  to place the content
+                       if (this.remoteDataMethod) {
+                               this.tpl = new Ext.Template("<div id=\"remData" + rowIndex + "\" class=\"rem-data-expand\"><\div>");
+                       }
+                       if (this.tpl && this.lazyRender) {
+                               body.innerHTML = this.getBodyContent(record, rowIndex);
+                       }
+
+                       return true;
+               }else{
+                       return false;
+               }
+       },
+
+       toggleRow : function(row) {
+               if (typeof row == 'number') {
+                       row = this.grid.view.getRow(row);
+               }
+               this[Ext.fly(row).hasClass('x-grid3-row-collapsed') ? 'expandRow' : 'collapseRow'](row);
+       },
+
+       expandRow : function(row) {
+               if (typeof row == 'number') {
+                       row = this.grid.view.getRow(row);
+               }
+               var record = this.grid.store.getAt(row.rowIndex);
+               var body = Ext.DomQuery.selectNode('tr:nth(2) div.x-grid3-row-body', row);
+               if (this.beforeExpand(record, body, row.rowIndex)) {
+                       this.state[record.id] = true;
+                       Ext.fly(row).replaceClass('x-grid3-row-collapsed', 'x-grid3-row-expanded');
+                       if (this.fireEvent('expand', this, record, body, row.rowIndex) !== false) {
+                               //  If the expand event is successful then get the remoteDataMethod
+                               this.getRemoteDataMethod(record,row.rowIndex);
+                       }
+               }
+       },
+
+       collapseRow : function(row) {
+               if (typeof row == 'number') {
+                       row = this.grid.view.getRow(row);
+               }
+               var record = this.grid.store.getAt(row.rowIndex);
+               var body = Ext.fly(row).child('tr:nth(1) div.x-grid3-row-body', true);
+               if (this.fireEvent('beforcollapse', this, record, body, row.rowIndex) !== false) {
+                       this.state[record.id] = false;
+                       Ext.fly(row).replaceClass('x-grid3-row-expanded', 'x-grid3-row-collapsed');
+                       this.fireEvent('collapse', this, record, body, row.rowIndex);
+               }
+       }
+});
index 69e77bc..b48153b 100644 (file)
@@ -1,42 +1,42 @@
-/* plugin for resize of grid in single container */\r
-Ext.namespace('Ext.ux.plugins');\r
-\r
-Ext.ux.plugins.FitToParent = Ext.extend(Object, {\r
-       constructor : function(parent) {\r
-               this.parent = parent;\r
-       },\r
-       init : function(c) {\r
-               c.on('render', function(c) {\r
-                       c.fitToElement = Ext.get(this.parent\r
-                                       || c.getPositionEl().dom.parentNode);\r
-                       if (!c.doLayout) {\r
-                               this.fitSizeToParent();\r
-                               Ext.EventManager.onWindowResize(this.fitSizeToParent, this);\r
-                       }\r
-               }, this, {\r
-                       single : true\r
-               });\r
-               if (c.doLayout) {\r
-                       c.monitorResize = true;\r
-                       c.doLayout = c.doLayout.createInterceptor(this.fitSizeToParent);\r
-               }\r
-       },\r
-\r
-       fitSizeToParent : function() {\r
-                       // Uses the dimension of the current viewport, but removes the document header\r
-               var documentHeaderHeight = 0;\r
-               var documentHeader = Ext.get('typo3-docheader');\r
-\r
-               if (Ext.isObject(documentHeader)) {\r
-                       documentHeaderHeight = documentHeader.getHeight();\r
-               }\r
-\r
-               this.fitToElement.setHeight(\r
-                       Ext.lib.Dom.getViewportHeight() - this.fitToElement.getTop() - documentHeaderHeight\r
-               );\r
-\r
-               var pos = this.getPosition(true), size = this.fitToElement.getViewSize();\r
-               this.setSize(size.width - pos[0], size.height - pos[1]);\r
-               \r
-       }\r
-});\r
+/* plugin for resize of grid in single container */
+Ext.namespace('Ext.ux.plugins');
+
+Ext.ux.plugins.FitToParent = Ext.extend(Object, {
+       constructor : function(parent) {
+               this.parent = parent;
+       },
+       init : function(c) {
+               c.on('render', function(c) {
+                       c.fitToElement = Ext.get(this.parent
+                                       || c.getPositionEl().dom.parentNode);
+                       if (!c.doLayout) {
+                               this.fitSizeToParent();
+                               Ext.EventManager.onWindowResize(this.fitSizeToParent, this);
+                       }
+               }, this, {
+                       single : true
+               });
+               if (c.doLayout) {
+                       c.monitorResize = true;
+                       c.doLayout = c.doLayout.createInterceptor(this.fitSizeToParent);
+               }
+       },
+
+       fitSizeToParent : function() {
+                       // Uses the dimension of the current viewport, but removes the document header
+               var documentHeaderHeight = 0;
+               var documentHeader = Ext.get('typo3-docheader');
+
+               if (Ext.isObject(documentHeader)) {
+                       documentHeaderHeight = documentHeader.getHeight();
+               }
+
+               this.fitToElement.setHeight(
+                       Ext.lib.Dom.getViewportHeight() - this.fitToElement.getTop() - documentHeaderHeight
+               );
+
+               var pos = this.getPosition(true), size = this.fitToElement.getViewSize();
+               this.setSize(size.width - pos[0], size.height - pos[1]);
+               
+       }
+});
index a659b93..2f47ac0 100644 (file)
-<?php\r
-/***************************************************************\r
- *  Copyright notice\r
- *\r
- *  (c) 2010 Kai Vogel (kai.vogel(at)speedprogs.de)\r
- *  All rights reserved\r
- *\r
- *  This script is part of the TYPO3 project. The TYPO3 project is\r
- *  free software; you can redistribute it and/or modify\r
- *  it under the terms of the GNU General Public License as published by\r
- *  the Free Software Foundation; either version 2 of the License, or\r
- *  (at your option) any later version.\r
- *\r
- *  The GNU General Public License can be found at\r
- *  http://www.gnu.org/copyleft/gpl.html.\r
- *  A copy is found in the textfile GPL.txt and important notices to the license\r
- *  from the author is found in LICENSE.txt distributed with these scripts.\r
- *\r
- *\r
- *  This script is distributed in the hope that it will be useful,\r
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- *  GNU General Public License for more details.\r
- *\r
- *  This copyright notice MUST APPEAR in all copies of the script!\r
- ***************************************************************/\r
-\r
-\r
-/**\r
- * Contains FlexForm manipulation methods as part of the TCEforms\r
- *\r
- * @author Kai Vogel <kai.vogel(at)speedprogs.de>\r
- */\r
-class t3lib_TCEforms_Flexforms extends t3lib_TCEforms {\r
-\r
-       /**\r
-        * Options that will be removed from config after creating items for a select to prevent double parsing\r
-        *\r
-        * @var array\r
-        */\r
-       protected $removeSelectConfig = array(\r
-               'itemsProcFunc',\r
-               'foreign_table',\r
-               'foreign_table_where',\r
-               'foreign_table_prefix',\r
-               'foreign_table_loadIcons',\r
-               'neg_foreign_table',\r
-               'neg_foreign_table_where',\r
-               'neg_foreign_table_prefix',\r
-               'neg_foreign_table_loadIcons',\r
-               'neg_foreign_table_imposeValueField',\r
-               'fileFolder',\r
-               'fileFolder_extList',\r
-               'fileFolder_recursions',\r
-               'MM',\r
-               'MM_opposite_field',\r
-               'MM_match_fields',\r
-               'MM_insert_fields',\r
-               'MM_table_where',\r
-               'MM_hasUidField',\r
-               'special',\r
-       );\r
-\r
-       /**\r
-        * Modify the Data Structure of a FlexForm field via TSconfig and group access lists\r
-        *\r
-        * @param array $dataStructure The data structure of the FlexForm field\r
-        * @param string $table The table name of the record\r
-        * @param string $tableField The field name\r
-        * @param array $tableRow The record data\r
-        * @param array $tableConf Additional configuration options\r
-        * @return array Modified FlexForm DS\r
-        * @see t3lib_TCEforms::getSingleField_typeFlex()\r
-        */\r
-       public function modifyFlexFormDS(array $dataStructure, $table, $tableField, array $tableRow, array $tableConf) {\r
-               $singleSheet = (!isset($dataStructure['sheets']) || !is_array($dataStructure['sheets']));\r
-               $metaConf = (!empty($dataStructure['meta']) ? $dataStructure['meta'] : array());\r
-               $sheetConf = array();\r
-\r
-                       // Get extension identifier (uses second pointer field if it's value is not empty, "list" or "*", else it must be a plugin and first one will be used)\r
-               $pointerFields = (!empty($tableConf['config']['ds_pointerField']) ? $tableConf['config']['ds_pointerField'] : 'list_type,CType');\r
-               $pointerFields = t3lib_div::trimExplode(',', $pointerFields);\r
-               $flexformIdentifier = (!empty($tableRow[$pointerFields[0]]) ? $tableRow[$pointerFields[0]] : '');\r
-               if (!empty($tableRow[$pointerFields[1]]) && $tableRow[$pointerFields[1]] != 'list' && $tableRow[$pointerFields[1]] != '*') {\r
-                       $flexformIdentifier = $tableRow[$pointerFields[1]];\r
-               }\r
-               if (empty($flexformIdentifier)) {\r
-                       return $dataStructure;\r
-               }\r
-\r
-                       // Get field configuration from page TSConfig\r
-               $TSconfig = $this->setTSconfig($table, $tableRow);\r
-               if (!empty($TSconfig[$tableField][$flexformIdentifier . '.'])) {\r
-                       $sheetConf = t3lib_div::removeDotsFromTS($TSconfig[$tableField][$flexformIdentifier . '.']);\r
-               }\r
-               ;\r
-\r
-                       // Get non-exclude-fields from group access lists\r
-               $nonExcludeFields = $this->getFlexFormNonExcludeFields($table, $tableField, $flexformIdentifier);\r
-\r
-                       // Load complete DS, including external file references\r
-               $dataStructure = t3lib_div::resolveAllSheetsInDS($dataStructure);\r
-\r
-                       // Modify flexform sheets\r
-               foreach ($dataStructure['sheets'] as $sheetName => $sheet) {\r
-                       if (empty($sheet['ROOT']['el']) || !is_array($sheet['ROOT']['el'])) {\r
-                               continue;\r
-                       }\r
-\r
-                               // Remove whole sheet (tab) if disabled\r
-                       if (!empty($sheetConf[$sheetName]['disabled'])) {\r
-                               unset($dataStructure['sheets'][$sheetName]);\r
-                               continue;\r
-                       }\r
-\r
-                               // Rename sheet (tab)\r
-                       if (!empty($sheetConf[$sheetName]['title'])) {\r
-                               $dataStructure['sheets'][$sheetName]['ROOT']['TCEforms']['sheetTitle'] = $sheetConf[$sheetName]['title'];\r
-                       }\r
-\r
-                               // Modify all configured fields in sheet\r
-                       $dataStructure['sheets'][$sheetName]['ROOT']['el'] = $this->modifySingleFlexFormSheet(\r
-                               $sheet['ROOT']['el'],\r
-                               $table,\r
-                               $tableField,\r
-                               $tableRow,\r
-                               (!empty($sheetConf[$sheetName]) ? $sheetConf[$sheetName] : array()),\r
-                               (!empty($nonExcludeFields[$sheetName]) ? $nonExcludeFields[$sheetName] : array())\r
-                       );\r
-\r
-                               // Remove empty sheet (tab)\r
-                       if (empty($dataStructure['sheets'][$sheetName]['ROOT']['el'])) {\r
-                               unset($dataStructure['sheets'][$sheetName]);\r
-                       }\r
-               }\r
-\r
-                       // Recover single flexform structure\r
-               if ($singleSheet && isset($dataStructure['sheets']['sDEF'])) {\r
-                       $dataStructure = $dataStructure['sheets']['sDEF'];\r
-               }\r
-\r
-                       // Recover meta configuration\r
-               if (!empty($metaConf)) {\r
-                       $dataStructure['meta'] = $metaConf;\r
-               }\r
-\r
-               return $dataStructure;\r
-       }\r
-\r
-       /**\r
-        * Modify a single FlexForm sheet according to given configuration\r
-        *\r
-        * @param array $sheet Flexform sheet to manipulate\r
-        * @param string $table The table name\r
-        * @param string $tableField The field name\r
-        * @param array $tableRow The record data\r
-        * @param array $sheetConf Sheet configuration\r
-        * @param array $nonExcludeFields Non-exclude-fields for this sheet\r
-        * @return array Modified sheet\r
-        * @see t3lib_TCEforms_flex::modifyFlexFormDS()\r
-        */\r
-       public function modifySingleFlexFormSheet(array $sheet, $table, $tableField, array $tableRow, array $sheetConf, array $nonExcludeFields) {\r
-               if (empty($sheet) || empty($table) || empty($tableField) || empty($tableRow)) {\r
-                       return $sheet;\r
-               }\r
-\r
-                       // Modify fields\r
-               foreach ($sheet as $fieldName => $field) {\r
-\r
-                               // Remove excluded fields\r
-                       if (!$GLOBALS['BE_USER']->isAdmin() && !empty($field['TCEforms']['exclude']) && empty($nonExcludeFields[$fieldName])) {\r
-                               unset($sheet[$fieldName]);\r
-                               continue;\r
-                       }\r
-\r
-                               // Stop here if no TSConfig was found for this field\r
-                       if (empty($sheetConf[$fieldName]) || !is_array($sheetConf[$fieldName])) {\r
-                               continue;\r
-                       }\r
-\r
-                               // Remove disabled fields\r
-                       if (!empty($sheetConf[$fieldName]['disabled'])) {\r
-                               unset($sheet[$fieldName]);\r
-                               continue;\r
-                       }\r
-\r
-                       $fieldConf = $sheetConf[$fieldName];\r
-                       $removeItems = (!empty($fieldConf['removeItems']) ? t3lib_div::trimExplode(',', $fieldConf['removeItems'], TRUE) : array());\r
-                       $keepItems = (!empty($fieldConf['keepItems']) ? t3lib_div::trimExplode(',', $fieldConf['keepItems'], TRUE) : array());\r
-                       $renameItems = (!empty($fieldConf['altLabels']) && is_array($fieldConf['altLabels']) ? $fieldConf['altLabels'] : array());\r
-                       $addItems = (!empty($fieldConf['addItems']) && is_array($fieldConf['addItems']) ? $fieldConf['addItems'] : array());\r
-\r
-                       unset($fieldConf['removeItems']);\r
-                       unset($fieldConf['keepItems']);\r
-                       unset($fieldConf['altLabels']);\r
-                       unset($fieldConf['addItems']);\r
-\r
-                               // Manipulate field\r
-                       if (!empty($field['TCEforms']) && is_array($field['TCEforms'])) {\r
-                               $sheet[$fieldName]['TCEforms'] = t3lib_div::array_merge_recursive_overrule($field['TCEforms'], $fieldConf);\r
-                       }\r
-\r
-                               // Manipulate only select fields, other field types will stop here\r
-                       if (empty($field['TCEforms']['config']['type']) || $field['TCEforms']['config']['type'] != 'select') {\r
-                               continue;\r
-                       }\r
-\r
-                               // Getting the selector box items from system\r
-                       $selItems = $this->addSelectOptionsToItemArray(\r
-                               $this->initItemArray($field['TCEforms']),\r
-                               $field['TCEforms'],\r
-                               $this->setTSconfig($table, $tableRow),\r
-                               $tableField\r
-                       );\r
-\r
-                               // Possibly filter some items\r
-                       $keepItemsFunc = create_function('$value', 'return $value[1];');\r
-                       $selItems = t3lib_div::keepItemsInArray($selItems, $keepItems, $keepItemsFunc);\r
-\r
-                               // Possibly add some items\r
-                       $selItems = $this->addItems($selItems, $addItems);\r
-\r
-                               // Process items by a user function\r
-                       if (!empty($field['TCEforms']['config']['itemsProcFunc'])) {\r
-                               $selItems = $this->procItems(\r
-                                       $selItems,\r
-                                       $fieldConf['config'],\r
-                                       $field['TCEforms']['config'],\r
-                                       $table,\r
-                                       $tableRow,\r
-                                       $tableField\r
-                               );\r
-                       }\r
-\r
-                               // Remove special configuration options after creating items to prevent double parsing\r
-                       foreach ($this->removeSelectConfig as $option) {\r
-                               unset($sheet[$fieldName]['TCEforms']['config'][$option]);\r
-                       }\r
-\r
-                               // Rename and remove items in select\r
-                       if ((!empty($removeItems) || !empty($renameItems)) && !empty($selItems) && is_array($selItems)) {\r
-                               foreach ($selItems as $itemKey => $itemConf) {\r
-                                               // Option has no key, no manipulation possible\r
-                                       if (!isset($itemConf[1])) {\r
-                                               continue;\r
-                                       }\r
-\r
-                                               // Remove\r
-                                       foreach ($removeItems as $removeKey => $removeValue) {\r
-                                               if (strcasecmp($removeValue, $itemConf[1]) == 0) {\r
-                                                       unset($selItems[$itemKey]);\r
-                                                       unset($removeItems[$removeKey]);\r
-                                               }\r
-                                       }\r
-\r
-                                               // Rename\r
-                                       foreach ($renameItems as $renameKey => $renameValue) {\r
-                                               if (strcasecmp($renameKey, $itemConf[1]) == 0) {\r
-                                                       $selItems[$itemKey][0] = $renameValue;\r
-                                                       unset($renameItems[$renameKey]);\r
-                                               }\r
-                                       }\r
-                               }\r
-                       }\r
-\r
-                       $sheet[$fieldName]['TCEforms']['config']['items'] = $selItems;\r
-\r
-               }\r
-\r
-               return $sheet;\r
-       }\r
-\r
-       /**\r
-        * Get FlexForm non-exclude-fields for current backend user\r
-        *\r
-        * @param string $table The table name\r
-        * @param string $tableField The field name\r
-        * @param string $extIdent The extension identifier\r
-        * @return array All non_exclude_fields from FlexForms\r
-        * @see t3lib_TCEforms::getSingleField_typeFlex()\r
-        */\r
-       protected function getFlexFormNonExcludeFields($table, $tableField, $extIdent) {\r
-               if (empty($GLOBALS['BE_USER']->groupData['non_exclude_fields']) || empty($table) || empty($tableField) || empty($extIdent)) {\r
-                       return array();\r
-               }\r
-\r
-               $accessListFields = t3lib_div::trimExplode(',', $GLOBALS['BE_USER']->groupData['non_exclude_fields']);\r
-               $identPrefix = $table . ':' . $tableField . ';' . $extIdent . ';';\r
-               $nonExcludeFields = array();\r
-\r
-                       // Collect only FlexForm fields\r
-               foreach ($accessListFields as $field) {\r
-                       if (strpos($field, $identPrefix) !== FALSE) {\r
-                               list(, , $sheetName, $fieldName) = explode(';', $field);\r
-                               $nonExcludeFields[$sheetName][$fieldName] = TRUE;\r
-                       }\r
-               }\r
-\r
-               return $nonExcludeFields;\r
-       }\r
-\r
-       /**\r
-        * Compare two arrays by their first value\r
-        *\r
-        * @param array $array1 First array\r
-        * @param array $array2 Second array\r
-        * @return integer Negative int if first array is lower, zero if both are identical, and positive if second is higher\r
-        */\r
-       public static function compareArraysByFirstValue(array $array1, array $array2) {\r
-               $array1 = reset($array1);\r
-               $array2 = reset($array2);\r
-\r
-               if (is_string($array1) && is_string($array2)) {\r
-                       return strcasecmp($array1, $array2);\r
-               }\r
-\r
-               return 0;\r
-       }\r
-\r
-}\r
-\r
-if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['classes/t3lib/tceforms/class.t3lib_tceforms_flexforms.php']) {\r
-       include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['classes/t3lib/tceforms/class.t3lib_tceforms_flexforms.php']);\r
-}\r
-\r
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010 Kai Vogel (kai.vogel(at)speedprogs.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!
+ ***************************************************************/
+
+
+/**
+ * Contains FlexForm manipulation methods as part of the TCEforms
+ *
+ * @author Kai Vogel <kai.vogel(at)speedprogs.de>
+ */
+class t3lib_TCEforms_Flexforms extends t3lib_TCEforms {
+
+       /**
+        * Options that will be removed from config after creating items for a select to prevent double parsing
+        *
+        * @var array
+        */
+       protected $removeSelectConfig = array(
+               'itemsProcFunc',
+               'foreign_table',
+               'foreign_table_where',
+               'foreign_table_prefix',
+               'foreign_table_loadIcons',
+               'neg_foreign_table',
+               'neg_foreign_table_where',
+               'neg_foreign_table_prefix',
+               'neg_foreign_table_loadIcons',
+               'neg_foreign_table_imposeValueField',
+               'fileFolder',
+               'fileFolder_extList',
+               'fileFolder_recursions',
+               'MM',
+               'MM_opposite_field',
+               'MM_match_fields',
+               'MM_insert_fields',
+               'MM_table_where',
+               'MM_hasUidField',
+               'special',
+       );
+
+       /**
+        * Modify the Data Structure of a FlexForm field via TSconfig and group access lists
+        *
+        * @param array $dataStructure The data structure of the FlexForm field
+        * @param string $table The table name of the record
+        * @param string $tableField The field name
+        * @param array $tableRow The record data
+        * @param array $tableConf Additional configuration options
+        * @return array Modified FlexForm DS
+        * @see t3lib_TCEforms::getSingleField_typeFlex()
+        */
+       public function modifyFlexFormDS(array $dataStructure, $table, $tableField, array $tableRow, array $tableConf) {
+               $singleSheet = (!isset($dataStructure['sheets']) || !is_array($dataStructure['sheets']));
+               $metaConf = (!empty($dataStructure['meta']) ? $dataStructure['meta'] : array());
+               $sheetConf = array();
+
+                       // Get extension identifier (uses second pointer field if it's value is not empty, "list" or "*", else it must be a plugin and first one will be used)
+               $pointerFields = (!empty($tableConf['config']['ds_pointerField']) ? $tableConf['config']['ds_pointerField'] : 'list_type,CType');
+               $pointerFields = t3lib_div::trimExplode(',', $pointerFields);
+               $flexformIdentifier = (!empty($tableRow[$pointerFields[0]]) ? $tableRow[$pointerFields[0]] : '');
+               if (!empty($tableRow[$pointerFields[1]]) && $tableRow[$pointerFields[1]] != 'list' && $tableRow[$pointerFields[1]] != '*') {
+                       $flexformIdentifier = $tableRow[$pointerFields[1]];
+               }
+               if (empty($flexformIdentifier)) {
+                       return $dataStructure;
+               }
+
+                       // Get field configuration from page TSConfig
+               $TSconfig = $this->setTSconfig($table, $tableRow);
+               if (!empty($TSconfig[$tableField][$flexformIdentifier . '.'])) {
+                       $sheetConf = t3lib_div::removeDotsFromTS($TSconfig[$tableField][$flexformIdentifier . '.']);
+               }
+               ;
+
+                       // Get non-exclude-fields from group access lists
+               $nonExcludeFields = $this->getFlexFormNonExcludeFields($table, $tableField, $flexformIdentifier);
+
+                       // Load complete DS, including external file references
+               $dataStructure = t3lib_div::resolveAllSheetsInDS($dataStructure);
+
+                       // Modify flexform sheets
+               foreach ($dataStructure['sheets'] as $sheetName => $sheet) {
+                       if (empty($sheet['ROOT']['el']) || !is_array($sheet['ROOT']['el'])) {
+                               continue;
+                       }
+
+                               // Remove whole sheet (tab) if disabled
+                       if (!empty($sheetConf[$sheetName]['disabled'])) {
+                               unset($dataStructure['sheets'][$sheetName]);
+                               continue;
+                       }
+
+                               // Rename sheet (tab)
+                       if (!empty($sheetConf[$sheetName]['title'])) {
+                               $dataStructure['sheets'][$sheetName]['ROOT']['TCEforms']['sheetTitle'] = $sheetConf[$sheetName]['title'];
+                       }
+
+                               // Modify all configured fields in sheet
+                       $dataStructure['sheets'][$sheetName]['ROOT']['el'] = $this->modifySingleFlexFormSheet(
+                               $sheet['ROOT']['el'],
+                               $table,
+                               $tableField,
+                               $tableRow,
+                               (!empty($sheetConf[$sheetName]) ? $sheetConf[$sheetName] : array()),
+                               (!empty($nonExcludeFields[$sheetName]) ? $nonExcludeFields[$sheetName] : array())
+                       );
+
+                               // Remove empty sheet (tab)
+                       if (empty($dataStructure['sheets'][$sheetName]['ROOT']['el'])) {
+                               unset($dataStructure['sheets'][$sheetName]);
+                       }
+               }
+
+                       // Recover single flexform structure
+               if ($singleSheet && isset($dataStructure['sheets']['sDEF'])) {
+                       $dataStructure = $dataStructure['sheets']['sDEF'];
+               }
+
+                       // Recover meta configuration
+               if (!empty($metaConf)) {
+                       $dataStructure['meta'] = $metaConf;
+               }
+
+               return $dataStructure;
+       }
+
+       /**
+        * Modify a single FlexForm sheet according to given configuration
+        *
+        * @param array $sheet Flexform sheet to manipulate
+        * @param string $table The table name
+        * @param string $tableField The field name
+        * @param array $tableRow The record data
+        * @param array $sheetConf Sheet configuration
+        * @param array $nonExcludeFields Non-exclude-fields for this sheet
+        * @return array Modified sheet
+        * @see t3lib_TCEforms_flex::modifyFlexFormDS()
+        */
+       public function modifySingleFlexFormSheet(array $sheet, $table, $tableField, array $tableRow, array $sheetConf, array $nonExcludeFields) {
+               if (empty($sheet) || empty($table) || empty($tableField) || empty($tableRow)) {
+                       return $sheet;
+               }
+
+                       // Modify fields
+               foreach ($sheet as $fieldName => $field) {
+
+                               // Remove excluded fields
+                       if (!$GLOBALS['BE_USER']->isAdmin() && !empty($field['TCEforms']['exclude']) && empty($nonExcludeFields[$fieldName])) {
+                               unset($sheet[$fieldName]);
+                               continue;
+                       }
+
+                               // Stop here if no TSConfig was found for this field
+                       if (empty($sheetConf[$fieldName]) || !is_array($sheetConf[$fieldName])) {
+                               continue;
+                       }
+
+                               // Remove disabled fields
+                       if (!empty($sheetConf[$fieldName]['disabled'])) {
+                               unset($sheet[$fieldName]);
+                               continue;
+                       }
+
+                       $fieldConf = $sheetConf[$fieldName];
+                       $removeItems = (!empty($fieldConf['removeItems']) ? t3lib_div::trimExplode(',', $fieldConf['removeItems'], TRUE) : array());
+                       $keepItems = (!empty($fieldConf['keepItems']) ? t3lib_div::trimExplode(',', $fieldConf['keepItems'], TRUE) : array());
+                       $renameItems = (!empty($fieldConf['altLabels']) && is_array($fieldConf['altLabels']) ? $fieldConf['altLabels'] : array());
+                       $addItems = (!empty($fieldConf['addItems']) && is_array($fieldConf['addItems']) ? $fieldConf['addItems'] : array());
+
+                       unset($fieldConf['removeItems']);
+                       unset($fieldConf['keepItems']);
+                       unset($fieldConf['altLabels']);
+                       unset($fieldConf['addItems']);
+
+                               // Manipulate field
+                       if (!empty($field['TCEforms']) && is_array($field['TCEforms'])) {
+                               $sheet[$fieldName]['TCEforms'] = t3lib_div::array_merge_recursive_overrule($field['TCEforms'], $fieldConf);
+                       }
+
+                               // Manipulate only select fields, other field types will stop here
+                       if (empty($field['TCEforms']['config']['type']) || $field['TCEforms']['config']['type'] != 'select') {
+                               continue;
+                       }
+
+                               // Getting the selector box items from system
+                       $selItems = $this->addSelectOptionsToItemArray(
+                               $this->initItemArray($field['TCEforms']),
+                               $field['TCEforms'],
+                               $this->setTSconfig($table, $tableRow),
+                               $tableField
+                       );
+
+                               // Possibly filter some items
+                       $keepItemsFunc = create_function('$value', 'return $value[1];');
+                       $selItems = t3lib_div::keepItemsInArray($selItems, $keepItems, $keepItemsFunc);
+
+                               // Possibly add some items
+                       $selItems = $this->addItems($selItems, $addItems);
+
+                               // Process items by a user function
+                       if (!empty($field['TCEforms']['config']['itemsProcFunc'])) {
+                               $selItems = $this->procItems(
+                                       $selItems,
+                                       $fieldConf['config'],
+                                       $field['TCEforms']['config'],
+                                       $table,
+                                       $tableRow,
+                                       $tableField
+                               );
+                       }
+
+                               // Remove special configuration options after creating items to prevent double parsing
+                       foreach ($this->removeSelectConfig as $option) {
+                               unset($sheet[$fieldName]['TCEforms']['config'][$option]);
+                       }
+
+                               // Rename and remove items in select
+                       if ((!empty($removeItems) || !empty($renameItems)) && !empty($selItems) && is_array($selItems)) {
+                               foreach ($selItems as $itemKey => $itemConf) {
+                                               // Option has no key, no manipulation possible
+                                       if (!isset($itemConf[1])) {
+                                               continue;
+                                       }
+
+                                               // Remove
+                                       foreach ($removeItems as $removeKey => $removeValue) {
+                                               if (strcasecmp($removeValue, $itemConf[1]) == 0) {
+                                                       unset($selItems[$itemKey]);
+                                                       unset($removeItems[$removeKey]);
+                                               }
+                                       }
+
+                                               // Rename
+                                       foreach ($renameItems as $renameKey => $renameValue) {
+                                               if (strcasecmp($renameKey, $itemConf[1]) == 0) {
+                                                       $selItems[$itemKey][0] = $renameValue;
+                                                       unset($renameItems[$renameKey]);
+                                               }
+                                       }
+                               }
+                       }
+
+                       $sheet[$fieldName]['TCEforms']['config']['items'] = $selItems;
+
+               }
+
+               return $sheet;
+       }
+
+       /**
+        * Get FlexForm non-exclude-fields for current backend user
+        *
+        * @param string $table The table name
+        * @param string $tableField The field name
+        * @param string $extIdent The extension identifier
+        * @return array All non_exclude_fields from FlexForms
+        * @see t3lib_TCEforms::getSingleField_typeFlex()
+        */
+       protected function getFlexFormNonExcludeFields($table, $tableField, $extIdent) {
+               if (empty($GLOBALS['BE_USER']->groupData['non_exclude_fields']) || empty($table) || empty($tableField) || empty($extIdent)) {
+                       return array();
+               }
+
+               $accessListFields = t3lib_div::trimExplode(',', $GLOBALS['BE_USER']->groupData['non_exclude_fields']);
+               $identPrefix = $table . ':' . $tableField . ';' . $extIdent . ';';
+               $nonExcludeFields = array();
+
+                       // Collect only FlexForm fields
+               foreach ($accessListFields as $field) {
+                       if (strpos($field, $identPrefix) !== FALSE) {
+                               list(, , $sheetName, $fieldName) = explode(';', $field);
+                               $nonExcludeFields[$sheetName][$fieldName] = TRUE;
+                       }
+               }
+
+               return $nonExcludeFields;
+       }
+
+       /**
+        * Compare two arrays by their first value
+        *
+        * @param array $array1 First array
+        * @param array $array2 Second array
+        * @return integer Negative int if first array is lower, zero if both are identical, and positive if second is higher
+        */
+       public static function compareArraysByFirstValue(array $array1, array $array2) {
+               $array1 = reset($array1);
+               $array2 = reset($array2);
+
+               if (is_string($array1) && is_string($array2)) {
+                       return strcasecmp($array1, $array2);
+               }
+
+               return 0;
+       }
+
+}
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['classes/t3lib/tceforms/class.t3lib_tceforms_flexforms.php']) {
+       include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['classes/t3lib/tceforms/class.t3lib_tceforms_flexforms.php']);
+}
+
 ?>
\ No newline at end of file
index 88a9d10..3480399 100644 (file)
-<?php\r
-/***************************************************************\r
-*  Copyright notice\r
-*\r
-*  (c) 2010 Stefan Galinski <stefan.galinski@gmail.com>\r
-*  All rights reserved\r
-*\r
-*  This script is part of the TYPO3 project. The TYPO3 project is\r
-*  free software; you can redistribute it and/or modify\r
-*  it under the terms of the GNU General Public License as published by\r
-*  the Free Software Foundation; either version 2 of the License, or\r
-*  (at your option) any later version.\r
-*\r
-*  The GNU General Public License can be found at\r
-*  http://www.gnu.org/copyleft/gpl.html.\r
-*\r
-*  This script is distributed in the hope that it will be useful,\r
-*  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-*  GNU General Public License for more details.\r
-*\r
-*  This copyright notice MUST APPEAR in all copies of the script!\r
-***************************************************************/\r
-\r
-/**\r
- * Testcase for class t3lib_tree_Node.\r
- *\r
- * @author Stefan Galinski <stefan.galinski@gmail.com>\r
- * @package TYPO3\r
- * @subpackage t3lib\r
- */\r
-class t3lib_tree_NodeTest extends tx_phpunit_testcase {\r
-       public function setUp() {\r
-       }\r
-\r
-       public function tearDown() {\r
-       }\r
-\r
-       protected function setUpNodeTestData() {\r
-               $fixture = new t3lib_tree_Node;\r
-               $fixture->setId('Root');\r
-\r
-               $nodeCollection = new t3lib_tree_NodeCollection;\r
-               for ($i = 0; $i < 10; ++$i) {\r
-                       $node = new t3lib_tree_Node;\r
-                       $node->setId($i);\r
-                       $node->setParentNode($fixture);\r
-\r
-                       $subNodeCollection = new t3lib_tree_NodeCollection;\r
-                       for ($j = 0; $j < 5; ++$j) {\r
-                               $subNode = new t3lib_tree_RepresentationNode;\r
-                               $subNode->setId($j);\r
-                               $subNode->setLabel('SubTest');\r
-                               $subNode->setType('Type');\r
-                               $subNode->setClass('Class');\r
-                               $subNode->setIcon('Icon');\r
-                               $subNode->setCallbackAction('Callback Action');\r
-                               $subNode->setParentNode($node);\r
-                               $subNodeCollection->append($subNode);\r
-                       }\r
-                       $node->setChildNodes($subNodeCollection);\r
-                       $nodeCollection->append($node);\r
-               }\r
-               $fixture->setChildNodes($nodeCollection);\r
-\r
-\r
-               return $fixture;\r
-       }\r
-\r
-       /**\r
-        * @test\r
-        */\r
-       public function serializeFixture() {\r
-               $expected = trim(file_get_contents(PATH_site . 'tests/t3lib/tree/fixtures/serialized.txt'));\r
-               $fixture = $this->setUpNodeTestData();\r
-               $serializedString = trim($fixture->serialize());\r
-               $this->assertSame($expected, $serializedString);\r
-       }\r
-\r
-       /**\r
-        * @test\r
-        */\r
-       public function deserializeFixture() {\r
-               $source = trim(file_get_contents(PATH_site . 'tests/t3lib/tree/fixtures/serialized.txt'));\r
-               $node = new t3lib_tree_Node;\r
-               $node->unserialize($source);\r
-               $serializedString = $node->serialize();\r
-               $this->assertSame($source, $serializedString);\r
-       }\r
-\r
-       /**\r
-        * @test\r
-        */\r
-       public function compareNodes() {\r
-               $node = new t3lib_tree_Node(array('id' => '15'));\r
-               $otherNode = new t3lib_tree_Node(array('id' => '5'));\r
-               $compareResult = $node->compareTo($otherNode);\r
-\r
-               $otherNode->setId('25');\r
-               $compareResult = $node->compareTo($otherNode);\r
-               $this->assertSame(-1, $compareResult);\r
-\r
-               $otherNode->setId('15');\r
-               $compareResult = $node->compareTo($otherNode);\r
-               $this->assertSame(0, $compareResult);\r
-       }\r
-}\r
-?>\r
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 Stefan Galinski <stefan.galinski@gmail.com>
+*  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.
+*
+*  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!
+***************************************************************/
+
+/**
+ * Testcase for class t3lib_tree_Node.
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @package TYPO3
+ * @subpackage t3lib
+ */
+class t3lib_tree_NodeTest extends tx_phpunit_testcase {
+       public function setUp() {
+       }
+
+       public function tearDown() {
+       }
+
+       protected function setUpNodeTestData() {
+               $fixture = new t3lib_tree_Node;
+               $fixture->setId('Root');
+
+               $nodeCollection = new t3lib_tree_NodeCollection;
+               for ($i = 0; $i < 10; ++$i) {
+                       $node = new t3lib_tree_Node;
+                       $node->setId($i);
+                       $node->setParentNode($fixture);
+
+                       $subNodeCollection = new t3lib_tree_NodeCollection;
+                       for ($j = 0; $j < 5; ++$j) {
+                               $subNode = new t3lib_tree_RepresentationNode;
+                               $subNode->setId($j);
+                               $subNode->setLabel('SubTest');
+                               $subNode->setType('Type');
+                               $subNode->setClass('Class');
+                               $subNode->setIcon('Icon');
+                               $subNode->setCallbackAction('Callback Action');
+                               $subNode->setParentNode($node);
+                               $subNodeCollection->append($subNode);
+                       }
+                       $node->setChildNodes($subNodeCollection);
+                       $nodeCollection->append($node);
+               }
+               $fixture->setChildNodes($nodeCollection);
+
+
+               return $fixture;
+       }
+
+       /**
+        * @test
+        */
+       public function serializeFixture() {
+               $expected = trim(file_get_contents(PATH_site . 'tests/t3lib/tree/fixtures/serialized.txt'));
+               $fixture = $this->setUpNodeTestData();
+               $serializedString = trim($fixture->serialize());
+               $this->assertSame($expected, $serializedString);
+       }
+
+       /**
+        * @test
+        */
+       public function deserializeFixture() {
+               $source = trim(file_get_contents(PATH_site . 'tests/t3lib/tree/fixtures/serialized.txt'));
+               $node = new t3lib_tree_Node;
+               $node->unserialize($source);
+               $serializedString = $node->serialize();
+               $this->assertSame($source, $serializedString);
+       }
+
+       /**
+        * @test
+        */
+       public function compareNodes() {
+               $node = new t3lib_tree_Node(array('id' => '15'));
+               $otherNode = new t3lib_tree_Node(array('id' => '5'));
+               $compareResult = $node->compareTo($otherNode);
+
+               $otherNode->setId('25');
+               $compareResult = $node->compareTo($otherNode);
+               $this->assertSame(-1, $compareResult);
+
+               $otherNode->setId('15');
+               $compareResult = $node->compareTo($otherNode);
+               $this->assertSame(0, $compareResult);
+       }
+}
+?>
index 16dce47..dae3fb8 100644 (file)
@@ -1,57 +1,57 @@
-<html xmlns="http://www.w3.org/1999/xhtml">\r
-  <head>\r
-    <script src="../../js/codemirror.js" type="text/javascript"></script>\r
-    <title>CodeMirror: Groovy demonstration</title>\r
-    <link rel="stylesheet" type="text/css" href="../../css/docs.css"/>\r
-  </head>\r
-  <body style="padding: 20px;">\r
-\r
-<p>Demonstration of <a href="../../index.html">CodeMirror</a>'s Groovy highlighter.</p>\r
-\r
-<p>Created by eXo Platform SAS (<a href="http://www.opensource.org/licenses/lgpl-2.1.php">license</a>).</p>\r
-\r
-<p>Note that the files for this parser aren't included in the CodeMirror repository, but have to fetched from <a href="http://svn.exoplatform.org/">svn.exoplatform.org</a>:</p>\r
-\r
-<ul>\r
- <li><a href="http://svn.exoplatform.org/projects/gwt/trunk/exo-gwtframework-editor/src/main/resources/org/exoplatform/gwtframework/editor/public/codemirror/js/tokenizegroovy.js">tokenizegroovy.js</a></li>\r
- <li><a href="http://svn.exoplatform.org/projects/gwt/trunk/exo-gwtframework-editor/src/main/resources/org/exoplatform/gwtframework/editor/public/codemirror/js/parsegroovy.js">parsegroovy.js</a></li>\r
- <li><a href="http://svn.exoplatform.org/projects/gwt/trunk/exo-gwtframework-editor/src/main/resources/org/exoplatform/gwtframework/editor/public/codemirror/css/groovycolors.css">groovy.colors.css</a></li>\r
-</ul>\r
-\r
-<div class="border">\r
-<textarea id="code" cols="120" rows="50">\r
-// simple groovy script\r
-import javax.ws.rs.Path\r
-import javax.ws.rs.GET\r
-import javax.ws.rs.PathParam\r
-import javax.ws.rs.POST\r
-\r
-@Path("/")\r
-public class HelloWorld {\r
-  @GET\r
-  @Path("helloworld/{name}")\r
-  public String hello(@PathParam("name") String name) {\r
-    return "Hello " + name\r
-  }\r
-  \r
-  @POST\r
-  @Path("helloworld/{name}")\r
-  public String hello2(@PathParam("name") String name) {\r
-    return "Hello " + name\r
-  }\r
-}\r
-</textarea>\r
-</div>\r
-\r
-<script type="text/javascript">\r
-  var editor = CodeMirror.fromTextArea('code', {\r
-    height: "450px",\r
-    parserfile: ["http://svn.exoplatform.org/projects/gwt/trunk/exo-gwtframework-editor/src/main/resources/org/exoplatform/gwtframework/editor/public/codemirror/js/parsegroovy.js", "http://svn.exoplatform.org/projects/gwt/trunk/exo-gwtframework-editor/src/main/resources/org/exoplatform/gwtframework/editor/public/codemirror/js/tokenizegroovy.js"],\r
-    stylesheet: "http://svn.exoplatform.org/projects/gwt/trunk/exo-gwtframework-editor/src/main/resources/org/exoplatform/gwtframework/editor/public/codemirror/css/groovycolors.css",\r
-    path: "../../js/",\r
-    textWrapping: false\r
-  });\r
-</script>\r
-\r
-</body>\r
-</html>\r
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <script src="../../js/codemirror.js" type="text/javascript"></script>
+    <title>CodeMirror: Groovy demonstration</title>
+    <link rel="stylesheet" type="text/css" href="../../css/docs.css"/>
+  </head>
+  <body style="padding: 20px;">
+
+<p>Demonstration of <a href="../../index.html">CodeMirror</a>'s Groovy highlighter.</p>
+
+<p>Created by eXo Platform SAS (<a href="http://www.opensource.org/licenses/lgpl-2.1.php">license</a>).</p>
+
+<p>Note that the files for this parser aren't included in the CodeMirror repository, but have to fetched from <a href="http://svn.exoplatform.org/">svn.exoplatform.org</a>:</p>
+
+<ul>
+ <li><a href="http://svn.exoplatform.org/projects/gwt/trunk/exo-gwtframework-editor/src/main/resources/org/exoplatform/gwtframework/editor/public/codemirror/js/tokenizegroovy.js">tokenizegroovy.js</a></li>
+ <li><a href="http://svn.exoplatform.org/projects/gwt/trunk/exo-gwtframework-editor/src/main/resources/org/exoplatform/gwtframework/editor/public/codemirror/js/parsegroovy.js">parsegroovy.js</a></li>
+ <li><a href="http://svn.exoplatform.org/projects/gwt/trunk/exo-gwtframework-editor/src/main/resources/org/exoplatform/gwtframework/editor/public/codemirror/css/groovycolors.css">groovy.colors.css</a></li>
+</ul>
+
+<div class="border">
+<textarea id="code" cols="120" rows="50">
+// simple groovy script
+import javax.ws.rs.Path
+import javax.ws.rs.GET
+import javax.ws.rs.PathParam
+import javax.ws.rs.POST
+
+@Path("/")
+public class HelloWorld {
+  @GET
+  @Path("helloworld/{name}")
+  public String hello(@PathParam("name") String name) {
+    return "Hello " + name
+  }
+  
+  @POST
+  @Path("helloworld/{name}")
+  public String hello2(@PathParam("name") String name) {
+    return "Hello " + name
+  }
+}
+</textarea>
+</div>
+
+<script type="text/javascript">
+  var editor = CodeMirror.fromTextArea('code', {
+    height: "450px",
+    parserfile: ["http://svn.exoplatform.org/projects/gwt/trunk/exo-gwtframework-editor/src/main/resources/org/exoplatform/gwtframework/editor/public/codemirror/js/parsegroovy.js", "http://svn.exoplatform.org/projects/gwt/trunk/exo-gwtframework-editor/src/main/resources/org/exoplatform/gwtframework/editor/public/codemirror/js/tokenizegroovy.js"],
+    stylesheet: "http://svn.exoplatform.org/projects/gwt/trunk/exo-gwtframework-editor/src/main/resources/org/exoplatform/gwtframework/editor/public/codemirror/css/groovycolors.css",
+    path: "../../js/",
+    textWrapping: false
+  });
+</script>
+
+</body>
+</html>
index 74a1a9c..2d24a6c 100644 (file)
@@ -1,73 +1,73 @@
-<?php\r
-/***************************************************************\r
- *  Copyright notice\r
- *\r
- *  (c) 2010 Steffen Kamper <steffen@typo3.org>\r
- *  All rights reserved\r
- *\r
- *  This script is part of the TYPO3 project. The TYPO3 project is\r
- *  free software; you can redistribute it and/or modify\r
- *  it under the terms of the GNU General Public License as published by\r
- *  the Free Software Foundation; either version 2 of the License, or\r
- *  (at your option) any later version.\r
- *\r
- *  The GNU General Public License can be found at\r
- *  http://www.gnu.org/copyleft/gpl.html.\r
- *  A copy is found in the textfile GPL.txt and important notices to the license\r
- *  from the author is found in LICENSE.txt distributed with these scripts.\r
- *\r
- *\r
- *  This script is distributed in the hope that it will be useful,\r
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- *  GNU General Public License for more details.\r
- *\r
- *  This copyright notice MUST APPEAR in all copies of the script!\r
- ***************************************************************/\r
-\r
-class tx_em_API {\r
-\r
-       /**\r
-        * @var array\r
-        */\r
-       public $typeLabels = array();\r
-\r
-       /**\r
-        * @var array\r
-        */\r
-       public $typeDescr = array();\r
-\r
-       /**\r
-        * @var array\r
-        */\r
-       public $typeBackPaths = array();\r
-\r
-\r
-       /**\r
-        * Constructor\r
-        *\r
-        * @return void\r
-        */\r
-       public function __construct() {\r
-\r
-               // load langauge file\r
-               $GLOBALS['LANG']->includeLLFile(t3lib_extMgm::extPath('em') . 'language/locallang.xml');\r
-\r
-               /**\r
-                * "TYPE" information; labels, paths, description etc.\r
-                */\r
-               $this->typeLabels = array(\r
-                       'S' => $GLOBALS['LANG']->getLL('type_system'),\r
-                       'G' => $GLOBALS['LANG']->getLL('type_global'),\r
-                       'L' => $GLOBALS['LANG']->getLL('type_local'),\r
-               );\r
-               $this->typeDescr = array(\r
-                       'S' => $GLOBALS['LANG']->getLL('descr_system'),\r
-                       'G' => $GLOBALS['LANG']->getLL('descr_global'),\r
-                       'L' => $GLOBALS['LANG']->getLL('descr_local'),\r
-               );\r
-\r
-\r
-\r
-       }\r
-}\r
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010 Steffen Kamper <steffen@typo3.org>
+ *  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 tx_em_API {
+
+       /**
+        * @var array
+        */
+       public $typeLabels = array();
+
+       /**
+        * @var array
+        */
+       public $typeDescr = array();
+
+       /**
+        * @var array
+        */
+       public $typeBackPaths = array();
+
+
+       /**
+        * Constructor
+        *
+        * @return void
+        */
+       public function __construct() {
+
+               // load langauge file
+               $GLOBALS['LANG']->includeLLFile(t3lib_extMgm::extPath('em') . 'language/locallang.xml');
+
+               /**
+                * "TYPE" information; labels, paths, description etc.
+                */
+               $this->typeLabels = array(
+                       'S' => $GLOBALS['LANG']->getLL('type_system'),
+                       'G' => $GLOBALS['LANG']->getLL('type_global'),
+                       'L' => $GLOBALS['LANG']->getLL('type_local'),
+               );
+               $this->typeDescr = array(
+                       'S' => $GLOBALS['LANG']->getLL('descr_system'),
+                       'G' => $GLOBALS['LANG']->getLL('descr_global'),
+                       'L' => $GLOBALS['LANG']->getLL('descr_local'),
+               );
+
+
+
+       }
+}
index 847ebe5..80c694a 100644 (file)
@@ -1,9 +1,9 @@
-\r
-###CSS_INCLUDE###\r
-###CSS_INLINE###\r
-\r
-###JS_LIBS###\r
-###JS_INCLUDE###\r
-###JS_INLINE###\r
-\r
-###HEADERDATA###\r
+
+###CSS_INCLUDE###
+###CSS_INLINE###
+
+###JS_LIBS###
+###JS_INCLUDE###
+###JS_INLINE###
+
+###HEADERDATA###
index 58524a1..e045a70 100644 (file)
-<?php\r
-/***************************************************************\r
-*  Copyright notice\r
-*\r
-*  (c) 2010 Tobias Liebig <mail_typo3@etobi.de>\r
-*  All rights reserved\r
-*\r
-*  This script is part of the TYPO3 project. The TYPO3 project is\r
-*  free software; you can redistribute it and/or modify\r
-*  it under the terms of the GNU General Public License as published by\r
-*  the Free Software Foundation; either version 2 of the License, or\r
-*  (at your option) any later version.\r
-*\r
-*  The GNU General Public License can be found at\r
-*  http://www.gnu.org/copyleft/gpl.html.\r
-*  A copy is found in the textfile GPL.txt and important notices to the license\r
-*  from the author is found in LICENSE.txt distributed with these scripts.\r
-*\r
-*\r
-*  This script is distributed in the hope that it will be useful,\r
-*  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-*  GNU General Public License for more details.\r
-*\r
-*  This copyright notice MUST APPEAR in all copies of the script!\r
-***************************************************************/\r
-\r
-require_once(t3lib_extMgm::extPath('t3editor', 'classes/class.tx_t3editor.php'));\r
-\r
-class tx_t3editor_hooks_fileedit {\r
-\r
-       /**\r
-        * @var tx_t3editor\r
-        */\r
-       protected $t3editor = NULL;\r
-\r
-       /**\r
-        * @var string\r
-        */\r
-       protected $ajaxSaveType = 'tx_tstemplateinfo';\r
-\r
-       /**\r
-        * @return tx_t3editor\r
-        */\r
-       protected function getT3editor() {\r
-               if ($this->t3editor == NULL) {\r
-                       $this->t3editor = t3lib_div::makeInstance('tx_t3editor')\r
-                               ->setAjaxSaveType($this->ajaxSaveType);\r
-               }\r
-               return $this->t3editor;\r
-       }\r
-\r
-       /**\r
-        * Hook-function: inject t3editor JavaScript code before the page is compiled\r
-        * called in file_edit.php:SC_file_edit->main\r
-        *\r
-        * @param array $parameters\r
-        * @param SC_file_edit $pObj\r
-        */\r
-       public function preOutputProcessingHook($parameters, $pObj) {\r
-               $t3editor = $this->getT3editor();\r
-               $t3editor->setModeByFile($parameters['target']);\r
-\r
-               if (!$t3editor->isEnabled() || !$t3editor->getMode()) {\r
-                       return;\r
-               }\r
-\r
-               $parameters['content'] = str_replace(\r
-                       '<!--###POSTJSMARKER###-->',\r
-                       '<!--###POSTJSMARKER###-->' . $t3editor->getModeSpecificJavascriptCode(),\r
-                       $parameters['content']\r
-               );\r
-       }\r
-\r
-       /**\r
-        * Hook-function: inject t3editor JavaScript code before the page is compiled\r
-        * called in typo3/template.php:startPage\r
-        *\r
-        * @param array $parameters\r
-        * @param template $pObj\r
-        */\r
-       public function preStartPageHook($parameters, $pObj) {\r
-               if (preg_match('/typo3\/file_edit\.php/', $_SERVER['SCRIPT_NAME'])) {\r
-                       $t3editor = $this->getT3editor();\r
-                       if (!$t3editor->isEnabled()) {\r
-                               return;\r
-                       }\r
-                       $pObj->JScode .= $t3editor->getJavascriptCode($pObj);\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Hook-function:\r
-        * called in file_edit.php:SC_file_edit->main\r
-        *\r
-        * @param array $parameters\r
-        * @param SC_file_edit $pObj\r
-        */\r
-       public function postOutputProcessingHook($parameters, $pObj) {\r
-               $t3editor = $this->getT3editor();\r
-\r
-               if (!$t3editor->isEnabled() || !$t3editor->getMode()) {\r
-                       return;\r
-               }\r
-\r
-               $attributes = 'rows="30" ' .\r
-                       'wrap="off" ' .\r
-                       $pObj->doc->formWidthText(48, 'width:98%;height:60%', 'off');\r
-\r
-               $title = $GLOBALS['LANG']->getLL('file') . ' ' .\r
-                       htmlspecialchars($pObj->target);\r
-\r
-               $outCode = $t3editor->getCodeEditor(\r
-                       'file[editfile][0][data]',\r
-                       'fixed-font enable-tab',\r
-                       '$1', // will be replaced with the actual code later, see preg_replace below\r
-                       $attributes,\r
-                       $title,\r
-                       array(\r
-                               'target' => intval($pObj->target)\r
-                       )\r
-               );\r
-\r
-               $parameters['pageContent'] = preg_replace(\r
-                       '/\<textarea .*name="file\[editfile\]\[0\]\[data\]".*\>([^\<]*)\<\/textarea\>/mi',\r
-                       $outCode,\r
-                       $parameters['pageContent']\r
-               );\r
-\r
-       }\r
-\r
-       /**\r
-        * @return boolean true if successful\r
-        */\r
-       public function save($parameters, $pObj) {\r
-               $savingsuccess = false;\r
-               if ($parameters['type'] == $this->ajaxSaveType) {\r
-                       require_once('init.php');\r
-                       require_once('classes/class.typo3_tcefile.php');\r
-\r
-                       $tceFile = t3lib_div::makeInstance('TYPO3_tcefile');\r
-                       $tceFile->processAjaxRequest(array(), $parameters['ajaxObj']);\r
-\r
-                       $result = $parameters['ajaxObj']->getContent('result');\r
-                       $savingsuccess = is_array($result) && $result['editfile'][0];\r
-               }\r
-               return $savingsuccess;\r
-       }\r
-}\r
-\r
-\r
-if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/t3editor/classes/class.tx_t3editor_hooks_fileedit.php']) {\r
-       include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/t3editor/classes/class.tx_t3editor_hooks_fileedit.php']);\r
-}\r
-\r
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 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_fileedit {
+
+       /**
+        * @var tx_t3editor
+        */
+       protected $t3editor = NULL;
+
+       /**
+        * @var string
+        */
+       protected $ajaxSaveType = 'tx_tstemplateinfo';
+
+       /**
+        * @return tx_t3editor
+        */
+       protected function getT3editor() {
+               if ($this->t3editor == NULL) {
+                       $this->t3editor = t3lib_div::makeInstance('tx_t3editor')
+                               ->setAjaxSaveType($this->ajaxSaveType);
+               }
+               return $this->t3editor;
+       }
+
+       /**
+        * Hook-function: inject t3editor JavaScript code before the page is compiled
+        * called in file_edit.php:SC_file_edit->main
+        *
+        * @param array $parameters
+        * @param SC_file_edit $pObj
+        */
+       public function preOutputProcessingHook($parameters, $pObj) {
+               $t3editor = $this->getT3editor();
+               $t3editor->setModeByFile($parameters['target']);
+
+               if (!$t3editor->isEnabled() || !$t3editor->getMode()) {
+                       return;
+               }
+
+               $parameters['content'] = str_replace(
+                       '<!--###POSTJSMARKER###-->',
+                       '<!--###POSTJSMARKER###-->' . $t3editor->getModeSpecificJavascriptCode(),
+                       $parameters['content']
+               );
+       }
+
+       /**
+        * 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) {
+               if (preg_match('/typo3\/file_edit\.php/', $_SERVER['SCRIPT_NAME'])) {
+                       $t3editor = $this->getT3editor();
+                       if (!$t3editor->isEnabled()) {
+                               return;
+                       }
+                       $pObj->JScode .= $t3editor->getJavascriptCode($pObj);
+               }
+       }
+
+       /**
+        * Hook-function:
+        * called in file_edit.php:SC_file_edit->main
+        *
+        * @param array $parameters
+        * @param SC_file_edit $pObj
+        */
+       public function postOutputProcessingHook($parameters, $pObj) {
+               $t3editor = $this->getT3editor();
+
+               if (!$t3editor->isEnabled() || !$t3editor->getMode()) {
+                       return;
+               }
+
+               $attributes = 'rows="30" ' .
+                       'wrap="off" ' .
+                       $pObj->doc->formWidthText(48, 'width:98%;height:60%', 'off');
+
+               $title = $GLOBALS['LANG']->getLL('file') . ' ' .
+                       htmlspecialchars($pObj->target);
+
+               $outCode = $t3editor->getCodeEditor(
+                       'file[editfile][0][data]',
+                       'fixed-font enable-tab',
+                       '$1', // will be replaced with the actual code later, see preg_replace below
+                       $attributes,
+                       $title,
+                       array(
+                               'target' => intval($pObj->target)
+                       )
+               );
+
+               $parameters['pageContent'] = preg_replace(
+                       '/\<textarea .*name="file\[editfile\]\[0\]\[data\]".*\>([^\<]*)\<\/textarea\>/mi',
+                       $outCode,
+                       $parameters['pageContent']
+               );
+
+       }
+
+       /**
+        * @return boolean true if successful
+        */
+       public function save($parameters, $pObj) {
+               $savingsuccess = false;
+               if ($parameters['type'] == $this->ajaxSaveType) {
+                       require_once('init.php');
+                       require_once('classes/class.typo3_tcefile.php');
+
+                       $tceFile = t3lib_div::makeInstance('TYPO3_tcefile');
+                       $tceFile->processAjaxRequest(array(), $parameters['ajaxObj']);
+
+                       $result = $parameters['ajaxObj']->getContent('result');
+                       $savingsuccess = is_array($result) && $result['editfile'][0];
+               }
+               return $savingsuccess;
+       }
+}
+
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/t3editor/classes/class.tx_t3editor_hooks_fileedit.php']) {
+       include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/t3editor/classes/class.tx_t3editor_hooks_fileedit.php']);
+}
+
 ?>
\ No newline at end of file
index 3fe6c15..bd85b79 100644 (file)
-/* TypoScript parser\r
- *\r
- * based on parsejavascript.js by Marijn Haverbeke\r
- *\r
- * A parser that can be plugged into the CodeMirror system has to\r
- * implement the following interface: It is a function that, when\r
- * called with a string stream (stringstream.js) as an argument,\r
- * returns a MochiKit-style iterator (object with a 'next' method).\r
- * This iterator, when called, consumes some input from the string\r
- * stream, and returns a token object. Token objects must have a\r
- * 'value' property (the text they represent), a 'style' property (the\r
- * CSS style that should be used to colour them). Tokens for newline\r
- * characters must also have a 'lexicalContext' property, which has an\r
- * 'indentation' method that can be used to determine the proper\r
- * indentation level for the next line. This method optionally takes\r
- * the first character of the next line as an argument, which it can\r
- * use to adjust the indentation level.\r
- *\r
- * So far this should be easy. The hard part is that the iterator\r
- * produced by the parse function must also have a 'copy' method. This\r
- * method, called without arguments, returns a function representing\r
- * the current state of the parser. When this function is later called\r
- * with a string stream as its argument, it returns a parser iterator\r
- * object that resumes parsing using the old state and the new input\r
- * stream. It may assume that only one parser is active at a time, and\r
- * clobber the state of the old parser (the implementation below\r
- * certianly does).\r
- */\r
-\r
-// Parse function for TypoScript. Makes use of the tokenizer from\r
-// tokenizetyposcript.js. Note that your parsers do not have to be\r
-// this complicated -- if you don't want to recognize local variables,\r
-// in many languages it is enough to just look for braces, semicolons,\r
-// parentheses, etc, and know when you are inside a string or comment.\r
-Editor.Parser = (function() {\r
-       // Token types that can be considered to be atoms.\r
-       var atomicTypes = {\r
-               "atom": true,\r
-               "number": true,\r
-               "variable": true,\r
-               "string": true,\r
-               "regexp": true\r
-       };\r
-\r
-       // Constructor for the lexical context objects.\r
-       function TSLexical(indented, column, type, align, prev) {\r
-               // indentation at start of this line\r
-               this.indented = indented;\r
-               // column at which this scope was opened\r
-               this.column = column;\r
-               // type of scope ('vardef', 'stat' (statement), '[', '{', or '(')\r
-               this.type = type;\r
-               // '[', '{', or '(' blocks that have any text after their opening\r
-               // character are said to be 'aligned' -- any lines below are\r
-               // indented all the way to the opening character.\r
-               if (align != null) {\r
-                       this.align = align;\r
-               }\r
-               // Parent scope, if any.\r
-               this.prev = prev;\r
-\r
-       }\r
-       \r
-       \r
-       // My favourite TypoScript indentation rules.\r
-       function indentTS(lexical) {\r
-               return function(firstChars) {\r
-                       var firstChar = firstChars && firstChars.charAt(0);\r
-                       var closing = firstChar == lexical.type;\r
-\r
-                       if (lexical.type == "{" && firstChar != "}") {\r
-                               return lexical.indented + 2;\r
-                       }\r
-\r
-                       if (firstChar == "}" && lexical.prev) {\r
-                               lexical = lexical.prev;\r
-                       }\r
-                       \r
-                       if (lexical.align) {\r
-                               return lexical.column - (closing ? 1: 0);\r
-                       } else {\r
-                               return lexical.indented + (closing ? 0: 2);\r
-                       }\r
-\r
-               };\r
-       }\r
-\r
-       // The parser-iterator-producing function itself.\r
-       function parseTS(input) {\r
-               // Wrap the input in a token stream\r
-               var tokens = tokenizeTypoScript(input);\r
-               // The parser state. cc is a stack of actions that have to be\r
-               // performed to finish the current statement. For example we might\r
-               // know that we still need to find a closing parenthesis and a\r
-               // semicolon. Actions at the end of the stack go first. It is\r
-               // initialized with an infinitely looping action that consumes\r
-               // whole statements.\r
-               var cc = [statements];\r
-               // Context contains information about the current local scope, the\r
-               // variables defined in that, and the scopes above it.\r
-               var context = null;\r
-               // The lexical scope, used mostly for indentation.\r
-               var lexical = new TSLexical( -2, 0, "block", false);\r
-               // Current column, and the indentation at the start of the current\r
-               // line. Used to create lexical scope objects.\r
-               var column = 0;\r
-               var indented = 0;\r
-               // Variables which are used by the mark, cont, and pass functions\r
-               // below to communicate with the driver loop in the 'next'\r
-               // function.\r
-               var consume,\r
-               marked;\r
-\r
-               // The iterator object.\r
-               var parser = {\r
-                       next: next,\r
-                       copy: copy\r
-               };\r
-\r
-               function next() {\r
-                       // Start by performing any 'lexical' actions (adjusting the\r
-                       // lexical variable), or the operations below will be working\r
-                       // with the wrong lexical state.\r
-                       while (cc[cc.length - 1].lex) {\r
-                               cc.pop()();\r
-                       }\r
-\r
-                       // Fetch a token.\r
-                       var token = tokens.next();\r
-                       // Adjust column and indented.\r
-                       if (token.type == "whitespace" && column == 0) {\r
-                               indented = token.value.length;\r
-                       }\r
-                       column += token.value.length;\r
-                       if (token.type == "newline") {\r
-                               indented = column = 0;\r
-                               // If the lexical scope's align property is still undefined at\r
-                               // the end of the line, it is an un-aligned scope.\r
-                               if (! ("align" in lexical)) {\r
-                                       lexical.align = false;\r
-                               }\r
-                       // Newline tokens get a lexical context associated with them,\r
-                               // which is used for indentation.\r
-                               token.indentation = indentTS(lexical);\r
-                       }\r
-                       // No more processing for meaningless tokens.\r
-                       if (token.type == "whitespace" || token.type == "newline" || token.type == "comment") {\r
-                               return token;\r
-                       }\r
-                       // When a meaningful token is found and the lexical scope's\r
-                       // align is undefined, it is an aligned scope.\r
-                       if (! ("align" in lexical)) {\r
-                               lexical.align = true;\r
-                       }\r
-                       // Execute actions until one 'consumes' the token and we can\r
-                       // return it. Marked is used to\r
-                       while (true) {\r
-                               consume = marked = false;\r
-                               // Take and execute the topmost action.\r
-                               cc.pop()(token.type, token.name);\r
-                               if (consume) {\r
-                                       // Marked is used to change the style of the current token.\r
-                                       if (marked) {\r
-                                               token.style = marked;\r
-                                       }\r
-                                       return token;\r
-                               }\r
-                       }\r
-               }\r
-\r
-               // This makes a copy of the parser state. It stores all the\r
-               // stateful variables in a closure, and returns a function that\r
-               // will restore them when called with a new input stream. Note\r
-               // that the cc array has to be copied, because it is contantly\r
-               // being modified. Lexical objects are not mutated, and context\r
-               // objects are not mutated in a harmful way, so they can be shared\r
-               // between runs of the parser.\r
-               function copy() {\r
-                       var _context = context,\r
-                       _lexical = lexical,\r
-                       _cc = cc.concat([]),\r
-                       _regexp = tokens.regexp,\r
-                       _comment = tokens.inComment;\r
-\r
-                       return function(input) {\r
-                               context = _context;\r
-                               lexical = _lexical;\r
-                               cc = _cc.concat([]);\r
-                               // copies the array\r
-                               column = indented = 0;\r
-                               tokens = tokenizeTypoScript(input);\r
-                               tokens.regexp = _regexp;\r
-                               tokens.inComment = _comment;\r
-                               return parser;\r
-                       };\r
-               }\r
-\r
-               // Helper function for pushing a number of actions onto the cc\r
-               // stack in reverse order.\r
-               function push(fs) {\r
-                       for (var i = fs.length - 1; i >= 0; i--) {\r
-                               cc.push(fs[i]);\r
-                       }\r
-               }\r
-\r
-               // cont and pass are used by the action functions to add other\r
-               // actions to the stack. cont will cause the current token to be\r
-               // consumed, pass will leave it for the next action.\r
-               function cont() {\r
-                       push(arguments);\r
-                       consume = true;\r
-               }\r
-\r
-               function pass() {\r
-                       push(arguments);\r
-                       consume = false;\r
-               }\r
-\r
-               // Used to change the style of the current token.\r
-               function mark(style) {\r
-                       marked = style;\r
-               }\r
-\r
-               // Push a new scope. Will automatically link the the current\r
-               // scope.\r
-               function pushcontext() {\r
-                       context = {\r
-                               prev: context,\r
-                               vars: {\r
-                                       "this": true,\r
-                                       "arguments": true\r
-                               }\r
-                       };\r
-               }\r
-\r
-               // Pop off the current scope.\r
-               function popcontext() {\r
-                       context = context.prev;\r
-               }\r
-\r
-               // Register a variable in the current scope.\r
-               function register(varname) {\r
-                       if (context) {\r
-                               mark("variabledef");\r
-                               context.vars[varname] = true;\r
-                       }\r
-               }\r
-\r
-               // Push a new lexical context of the given type.\r
-               function pushlex(type) {\r
-                       var result = function() {\r
-                               lexical = new TSLexical(indented, column, type, null, lexical)\r
-                       };\r
-                       result.lex = true;\r
-                       return result;\r
-               }\r
-\r
-               // Pop off the current lexical context.\r
-               function poplex() {\r
-                       lexical = lexical.prev;\r
-               }\r
-\r
-               poplex.lex = true;\r
-               // The 'lex' flag on these actions is used by the 'next' function\r
-               // to know they can (and have to) be ran before moving on to the\r
-               // next token.\r
-\r
-               // Creates an action that discards tokens until it finds one of\r
-               // the given type.\r
-               function expect(wanted) {\r
-                       return function(type) {\r
-                               if (type == wanted) {\r
-                                       cont();\r
-                               } else {\r
-                                       cont(arguments.callee);\r
-                               }\r
-                       };\r
-               }\r
-\r
-               // Looks for a statement, and then calls itself.\r
-               function statements(type) {\r
-                       return pass(statement, statements);\r
-               }\r
-               // Dispatches various types of statements based on the type of the\r
-               // current token.\r
-               function statement(type) {\r
-                       if (type == "{") {\r
-                               cont(pushlex("{"), block, poplex);\r
-                       } else {\r
-                               cont();\r
-                       }\r
-               }\r
-\r
-               // Dispatch expression types.\r
-               function expression(type) {\r
-                       if (atomicTypes.hasOwnProperty(type)) {\r
-                               cont(maybeoperator);\r
-\r
-                       } else if (type == "function") {\r
-                               cont(functiondef);\r
-\r
-                       } else if (type == "keyword c") {\r
-                               cont(expression);\r
-\r
-                       } else if (type == "(") {\r
-                               cont(pushlex(")"), expression, expect(")"), poplex);\r
-\r
-                       } else if (type == "operator") {\r
-                               cont(expression);\r
-\r
-                       } else if (type == "[") {\r
-                               cont(pushlex("]"), commasep(expression), expect("]"), poplex);\r
-\r
-                       } else if (type == "{") {\r
-                               cont(pushlex("}"), commasep(objprop), expect("}"), poplex);\r
-                       }\r
-               }\r
-\r
-               // Called for places where operators, function calls, or\r
-               // subscripts are valid. Will skip on to the next action if none\r
-               // is found.\r
-               function maybeoperator(type) {\r
-                       if (type == "operator") {\r
-                               cont(expression);\r
-\r
-                       } else if (type == "(") {\r
-                               cont(pushlex(")"), expression, commasep(expression), expect(")"), poplex);\r
-\r
-                       } else if (type == ".") {\r
-                               cont(property, maybeoperator);\r
-\r
-                       } else if (type == "[") {\r
-                               cont(pushlex("]"), expression, expect("]"), poplex);\r
-                       }\r
-               }\r
-\r
-               // When a statement starts with a variable name, it might be a\r
-               // label. If no colon follows, it's a regular statement.\r
-               function maybelabel(type) {\r
-                       if (type == ":") {\r
-                               cont(poplex, statement);\r
-                       } else {\r
-                               pass(maybeoperator, expect(";"), poplex);\r
-                       }\r
-               }\r
-\r
-               // Property names need to have their style adjusted -- the\r
-               // tokenizer think they are variables.\r
-               function property(type) {\r
-                       if (type == "variable") {\r
-                               mark("property");\r
-                               cont();\r
-                       }\r
-               }\r
-\r
-               // This parses a property and its value in an object literal.\r
-               function objprop(type) {\r
-                       if (type == "variable") {\r
-                               mark("property");\r
-                       }\r
-                       if (atomicTypes.hasOwnProperty(type)) {\r
-                               cont(expect(":"), expression);\r
-                       }\r
-               }\r
-\r
-               // Parses a comma-separated list of the things that are recognized\r
-               // by the 'what' argument.\r
-               function commasep(what) {\r
-                       function proceed(type) {\r
-                               if (type == ",") {\r
-                                       cont(what, proceed);\r
-                               }\r
-                       };\r
-                       return function() {\r
-                               pass(what, proceed);\r
-                       };\r
-               }\r
-\r
-               // Look for statements until a closing brace is found.\r
-               function block(type) {\r
-                       if (type == "}") {\r
-                               cont();\r
-                       } else {\r
-                               pass(statement, block);\r
-                       }\r
-               }\r
-\r
-               // Look for statements until a closing brace is found.\r
-               function condition(type) {\r
-                       if (type == "]") {\r
-                               cont();\r
-                       } else {\r
-                               pass(statement, block);\r
-                       }\r
-               }\r
-\r
-               // Variable definitions are split into two actions -- 1 looks for\r
-               // a name or the end of the definition, 2 looks for an '=' sign or\r
-               // a comma.\r
-               function vardef1(type, value) {\r
-                       if (type == "variable") {\r
-                               register(value);\r
-                               cont(vardef2);\r
-                       } else {\r
-                               cont();\r
-                       }\r
-               }\r
-\r
-               function vardef2(type) {\r
-                       if (type == "operator") {\r
-                               cont(expression, vardef2);\r
-                       } else if (type == ",") {\r
-                               cont(vardef1);\r
-                       }\r
-               }\r
-\r
-               // For loops.\r
-               function forspec1(type, value) {\r
-                       if (type == "var") {\r
-                               cont(vardef1, forspec2);\r
-                       } else {\r
-                               cont(expression, forspec2);\r
-                       }\r
-               }\r
-\r
-               function forspec2(type) {\r
-                       if (type == ",") {\r
-                               cont(forspec1);\r
-                       }\r
-                       if (type == ";") {\r
-                               cont(expression, expect(";"), expression);\r
-                       }\r
-               }\r
-\r
-               // A function definition creates a new context, and the variables\r
-               // in its argument list have to be added to this context.\r
-               function functiondef(type, value) {\r
-                       if (type == "variable") {\r
-                               register(value);\r
-                               cont(functiondef);\r
-                       } else if (type == "(") {\r
-                               cont(pushcontext, commasep(funarg), expect(")"), statement, popcontext);\r
-                       }\r
-               }\r
-\r
-               function funarg(type, value) {\r
-                       if (type == "variable") {\r
-                               register(value);\r
-                               cont();\r
-                       }\r
-               }\r
-\r
-               return parser;\r
-       }\r
-       \r
-       return {make: parseTS, electricChars: "{}"};\r
-})();\r
-/* TypoScript parser\r
- *\r
- * based on parsejavascript.js by Marijn Haverbeke\r
- *\r
- * A parser that can be plugged into the CodeMirror system has to\r
- * implement the following interface: It is a function that, when\r
- * called with a string stream (stringstream.js) as an argument,\r
- * returns a MochiKit-style iterator (object with a 'next' method).\r
- * This iterator, when called, consumes some input from the string\r
- * stream, and returns a token object. Token objects must have a\r
- * 'value' property (the text they represent), a 'style' property (the\r
- * CSS style that should be used to colour them). Tokens for newline\r
- * characters must also have a 'lexicalContext' property, which has an\r
- * 'indentation' method that can be used to determine the proper\r
- * indentation level for the next line. This method optionally takes\r
- * the first character of the next line as an argument, which it can\r
- * use to adjust the indentation level.\r
- *\r
- * So far this should be easy. The hard part is that the iterator\r
- * produced by the parse function must also have a 'copy' method. This\r
- * method, called without arguments, returns a function representing\r
- * the current state of the parser. When this function is later called\r
- * with a string stream as its argument, it returns a parser iterator\r
- * object that resumes parsing using the old state and the new input\r
- * stream. It may assume that only one parser is active at a time, and\r
- * clobber the state of the old parser (the implementation below\r
- * certianly does).\r
- */\r
-\r
-// Parse function for TypoScript. Makes use of the tokenizer from\r
-// tokenizetyposcript.js. Note that your parsers do not have to be\r
-// this complicated -- if you don't want to recognize local variables,\r
-// in many languages it is enough to just look for braces, semicolons,\r
-// parentheses, etc, and know when you are inside a string or comment.\r
-Editor.Parser = (function() {\r
-       // Token types that can be considered to be atoms.\r
-       var atomicTypes = {\r
-               "atom": true,\r
-               "number": true,\r
-               "variable": true,\r
-               "string": true,\r
-               "regexp": true\r
-       };\r
-\r
-       // Constructor for the lexical context objects.\r
-       function TSLexical(indented, column, type, align, prev) {\r
-               // indentation at start of this line\r
-               this.indented = indented;\r
-               // column at which this scope was opened\r
-               this.column = column;\r
-               // type of scope ('vardef', 'stat' (statement), '[', '{', or '(')\r
-               this.type = type;\r
-               // '[', '{', or '(' blocks that have any text after their opening\r
-               // character are said to be 'aligned' -- any lines below are\r
-               // indented all the way to the opening character.\r
-               if (align != null) {\r
-                       this.align = align;\r
-               }\r
-               // Parent scope, if any.\r
-               this.prev = prev;\r
-\r
-       }\r
-       \r
-       \r
-       // My favourite TypoScript indentation rules.\r
-       function indentTS(lexical) {\r
-               return function(firstChars) {\r
-                       var firstChar = firstChars && firstChars.charAt(0);\r
-                       var closing = firstChar == lexical.type;\r
-\r
-                       if (lexical.type == "{" && firstChar != "}") {\r
-                               return lexical.indented + 2;\r
-                       }\r
-\r
-                       if (firstChar == "}" && lexical.prev) {\r
-                               lexical = lexical.prev;\r
-                       }\r
-                       \r
-                       if (lexical.align) {\r
-                               return lexical.column - (closing ? 1: 0);\r
-                       } else {\r
-                               return lexical.indented + (closing ? 0: 2);\r
-                       }\r
-\r
-               };\r
-       }\r
-\r
-       // The parser-iterator-producing function itself.\r
-       function parseTS(input) {\r
-               // Wrap the input in a token stream\r
-               var tokens = tokenizeTypoScript(input);\r
-               // The parser state. cc is a stack of actions that have to be\r
-               // performed to finish the current statement. For example we might\r
-               // know that we still need to find a closing parenthesis and a\r
-               // semicolon. Actions at the end of the stack go first. It is\r
-               // initialized with an infinitely looping action that consumes\r
-               // whole statements.\r
-               var cc = [statements];\r
-               // Context contains information about the current local scope, the\r
-               // variables defined in that, and the scopes above it.\r
-               var context = null;\r
-               // The lexical scope, used mostly for indentation.\r
-               var lexical = new TSLexical( -2, 0, "block", false);\r
-               // Current column, and the indentation at the start of the current\r
-               // line. Used to create lexical scope objects.\r
-               var column = 0;\r
-               var indented = 0;\r
-               // Variables which are used by the mark, cont, and pass functions\r
-               // below to communicate with the driver loop in the 'next'\r
-               // function.\r
-               var consume,\r
-               marked;\r
-\r
-               // The iterator object.\r
-               var parser = {\r
-                       next: next,\r
-                       copy: copy\r
-               };\r
-\r
-               function next() {\r
-                       // Start by performing any 'lexical' actions (adjusting the\r
-                       // lexical variable), or the operations below will be working\r
-                       // with the wrong lexical state.\r
-                       while (cc[cc.length - 1].lex) {\r
-                               cc.pop()();\r
-                       }\r
-\r
-                       // Fetch a token.\r
-                       var token = tokens.next();\r
-                       // Adjust column and indented.\r
-                       if (token.type == "whitespace" && column == 0) {\r
-                               indented = token.value.length;\r
-                       }\r
-                       column += token.value.length;\r
-                       if (token.type == "newline") {\r
-                               indented = column = 0;\r
-                               // If the lexical scope's align property is still undefined at\r
-                               // the end of the line, it is an un-aligned scope.\r
-                               if (! ("align" in lexical)) {\r
-                                       lexical.align = false;\r
-                               }\r
-                       // Newline tokens get a lexical context associated with them,\r
-                               // which is used for indentation.\r
-                               token.indentation = indentTS(lexical);\r
-                       }\r
-                       // No more processing for meaningless tokens.\r
-                       if (token.type == "whitespace" || token.type == "newline" || token.type == "comment") {\r
-                               return token;\r
-                       }\r
-                       // When a meaningful token is found and the lexical scope's\r
-                       // align is undefined, it is an aligned scope.\r
-                       if (! ("align" in lexical)) {\r
-                               lexical.align = true;\r
-                       }\r
-                       // Execute actions until one 'consumes' the token and we can\r
-                       // return it. Marked is used to\r
-                       while (true) {\r
-                               consume = marked = false;\r
-                               // Take and execute the topmost action.\r
-                               cc.pop()(token.type, token.name);\r
-                               if (consume) {\r
-                                       // Marked is used to change the style of the current token.\r
-                                       if (marked) {\r
-                                               token.style = marked;\r
-                                       }\r
-                                       return token;\r
-                               }\r
-                       }\r
-               }\r
-\r
-               // This makes a copy of the parser state. It stores all the\r
-               // stateful variables in a closure, and returns a function that\r
-               // will restore them when called with a new input stream. Note\r
-               // that the cc array has to be copied, because it is contantly\r
-               // being modified. Lexical objects are not mutated, and context\r
-               // objects are not mutated in a harmful way, so they can be shared\r
-               // between runs of the parser.\r
-               function copy() {\r
-                       var _context = context,\r
-                       _lexical = lexical,\r
-                       _cc = cc.concat([]),\r
-                       _regexp = tokens.regexp,\r
-                       _comment = tokens.inComment;\r
-\r
-                       return function(input) {\r
-                               context = _context;\r
-                               lexical = _lexical;\r
-                               cc = _cc.concat([]);\r
-                               // copies the array\r
-                               column = indented = 0;\r
-                               tokens = tokenizeTypoScript(input);\r
-                               tokens.regexp = _regexp;\r
-                               tokens.inComment = _comment;\r
-                               return parser;\r
-                       };\r
-               }\r
-\r
-               // Helper function for pushing a number of actions onto the cc\r
-               // stack in reverse order.\r
-               function push(fs) {\r
-                       for (var i = fs.length - 1; i >= 0; i--) {\r
-                               cc.push(fs[i]);\r
-                       }\r
-               }\r
-\r
-               // cont and pass are used by the action functions to add other\r
-               // actions to the stack. cont will cause the current token to be\r
-               // consumed, pass will leave it for the next action.\r
-               function cont() {\r
-                       push(arguments);\r
-                       consume = true;\r
-               }\r
-\r
-               function pass() {\r
-                       push(arguments);\r
-                       consume = false;\r
-               }\r
-\r
-               // Used to change the style of the current token.\r
-               function mark(style) {\r
-                       marked = style;\r
-               }\r
-\r
-               // Push a new scope. Will automatically link the the current\r
-               // scope.\r
-               function pushcontext() {\r
-                       context = {\r
-                               prev: context,\r
-                               vars: {\r
-                                       "this": true,\r
-                                       "arguments": true\r
-                               }\r
-                       };\r
-               }\r
-\r
-               // Pop off the current scope.\r
-               function popcontext() {\r
-                       context = context.prev;\r
-               }\r
-\r
-               // Register a variable in the current scope.\r
-               function register(varname) {\r
-                       if (context) {\r
-                               mark("variabledef");\r
-                               context.vars[varname] = true;\r
-                       }\r
-               }\r
-\r
-               // Push a new lexical context of the given type.\r
-               function pushlex(type) {\r
-                       var result = function() {\r
-                               lexical = new TSLexical(indented, column, type, null, lexical)\r
-                       };\r
-                       result.lex = true;\r
-                       return result;\r
-               }\r
-\r
-               // Pop off the current lexical context.\r
-               function poplex() {\r
-                       lexical = lexical.prev;\r
-               }\r
-\r
-               poplex.lex = true;\r
-               // The 'lex' flag on these actions is used by the 'next' function\r
-               // to know they can (and have to) be ran before moving on to the\r
-               // next token.\r
-\r
-               // Creates an action that discards tokens until it finds one of\r
-               // the given type.\r
-               function expect(wanted) {\r
-                       return function(type) {\r
-                               if (type == wanted) {\r
-                                       cont();\r
-                               } else {\r
-                                       cont(arguments.callee);\r
-                               }\r
-                       };\r
-               }\r
-\r
-               // Looks for a statement, and then calls itself.\r
-               function statements(type) {\r
-                       return pass(statement, statements);\r
-               }\r
-               // Dispatches various types of statements based on the type of the\r
-               // current token.\r
-               function statement(type) {\r
-                       if (type == "{") {\r
-                               cont(pushlex("{"), block, poplex);\r
-                       } else {\r
-                               cont();\r
-                       }\r
-               }\r
-\r
-               // Dispatch expression types.\r
-               function expression(type) {\r
-                       if (atomicTypes.hasOwnProperty(type)) {\r
-                               cont(maybeoperator);\r
-\r
-                       } else if (type == "function") {\r
-                               cont(functiondef);\r
-\r
-                       } else if (type == "keyword c") {\r
-                               cont(expression);\r
-\r
-                       } else if (type == "(") {\r
-                               cont(pushlex(")"), expression, expect(")"), poplex);\r
-\r
-                       } else if (type == "operator") {\r
-                               cont(expression);\r
-\r
-                       } else if (type == "[") {\r
-                               cont(pushlex("]"), commasep(expression), expect("]"), poplex);\r
-\r
-                       } else if (type == "{") {\r
-                               cont(pushlex("}"), commasep(objprop), expect("}"), poplex);\r
-                       }\r
-               }\r
-\r
-               // Called for places where operators, function calls, or\r
-               // subscripts are valid. Will skip on to the next action if none\r
-               // is found.\r
-               function maybeoperator(type) {\r
-                       if (type == "operator") {\r
-                               cont(expression);\r
-\r
-                       } else if (type == "(") {\r
-                               cont(pushlex(")"), expression, commasep(expression), expect(")"), poplex);\r
-\r
-                       } else if (type == ".") {\r
-                               cont(property, maybeoperator);\r
-\r
-                       } else if (type == "[") {\r
-                               cont(pushlex("]"), expression, expect("]"), poplex);\r
-                       }\r
-               }\r
-\r
-               // When a statement starts with a variable name, it might be a\r
-               // label. If no colon follows, it's a regular statement.\r
-               function maybelabel(type) {\r
-                       if (type == ":") {\r
-                               cont(poplex, statement);\r
-                       } else {\r
-                               pass(maybeoperator, expect(";"), poplex);\r
-                       }\r
-               }\r
-\r
-               // Property names need to have their style adjusted -- the\r
-               // tokenizer think they are variables.\r
-               function property(type) {\r
-                       if (type == "variable") {\r
-                               mark("property");\r
-                               cont();\r
-                       }\r
-               }\r
-\r
-               // This parses a property and its value in an object literal.\r
-               function objprop(type) {\r
-                       if (type == "variable") {\r
-                               mark("property");\r
-                       }\r
-                       if (atomicTypes.hasOwnProperty(type)) {\r
-                               cont(expect(":"), expression);\r
-                       }\r
-               }\r
-\r
-               // Parses a comma-separated list of the things that are recognized\r
-               // by the 'what' argument.\r
-               function commasep(what) {\r
-                       function proceed(type) {\r
-                               if (type == ",") {\r
-                                       cont(what, proceed);\r
-                               }\r
-                       };\r
-                       return function() {\r
-                               pass(what, proceed);\r
-                       };\r
-               }\r
-\r
-               // Look for statements until a closing brace is found.\r
-               function block(type) {\r
-                       if (type == "}") {\r
-                               cont();\r
-                       } else {\r
-                               pass(statement, block);\r
-                       }\r
-               }\r
-\r
-               // Look for statements until a closing brace is found.\r
-               function condition(type) {\r
-                       if (type == "]") {\r
-                               cont();\r
-                       } else {\r
-                               pass(statement, block);\r
-                       }\r
-               }\r
-\r
-               // Variable definitions are split into two actions -- 1 looks for\r
-               // a name or the end of the definition, 2 looks for an '=' sign or\r
-               // a comma.\r
-               function vardef1(type, value) {\r
-                       if (type == "variable") {\r
-                               register(value);\r
-                               cont(vardef2);\r
-                       } else {\r
-                               cont();\r
-                       }\r
-               }\r
-\r
-               function vardef2(type) {\r
-                       if (type == "operator") {\r
-                               cont(expression, vardef2);\r
-                       } else if (type == ",") {\r
-                               cont(vardef1);\r
-                       }\r
-               }\r
-\r
-               // For loops.\r
-               function forspec1(type, value) {\r
-                       if (type == "var") {\r
-                               cont(vardef1, forspec2);\r
-                       } else {\r
-                               cont(expression, forspec2);\r
-                       }\r
-               }\r
-\r
-               function forspec2(type) {\r
-                       if (type == ",") {\r
-                               cont(forspec1);\r
-                       }\r
-                       if (type == ";") {\r
-                               cont(expression, expect(";"), expression);\r
-                       }\r
-               }\r
-\r
-               // A function definition creates a new context, and the variables\r
-               // in its argument list have to be added to this context.\r
-               function functiondef(type, value) {\r
-                       if (type == "variable") {\r
-                               register(value);\r
-                               cont(functiondef);\r
-                       } else if (type == "(") {\r
-                               cont(pushcontext, commasep(funarg), expect(")"), statement, popcontext);\r
-                       }\r
-               }\r
-\r
-               function funarg(type, value) {\r
-                       if (type == "variable") {\r
-                               register(value);\r
-                               cont();\r
-                       }\r
-               }\r
-\r
-               return parser;\r
-       }\r
-       \r
-       return {make: parseTS, electricChars: "{}"};\r
-})();\r
+/* 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: "{}"};
+})();
+/* 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: "{}"};
+})();
index 2dcb96f..0d01e10 100644 (file)
-/* Tokenizer for TypoScript code\r
- *\r
- * based on tokenizejavascript.js by Marijn Haverbeke\r
- */\r
-\r
-// List of "reserved" word in typoscript and a css-class\r
-var typoscriptWords = {\r
-       '_CSS_DEFAULT_STYLE': 'keyword',\r
-       '_DEFAULT_PI_VARS': 'keyword',\r
-       '_GIFBUILDER': 'keyword',\r
-       '_LOCAL_LANG': 'keyword',\r
-       'CARRAY': 'keyword',\r
-       'CASE': 'keyword',\r
-       'CLEARGIF': 'keyword',\r
-       'COA': 'keyword',\r
-       'COA_INT': 'keyword',\r
-       'COBJ_ARRAY': 'keyword',\r
-       'COLUMNS': 'keyword',\r
-       'CONFIG': 'keyword',\r
-       'CONSTANTS': 'keyword',\r
-       'CONTENT': 'keyword',\r
-       'CTABLE': 'keyword',\r
-       'CType': 'keyword',\r
-       'DB': 'keyword',\r
-       'DOCUMENT_BODY': 'keyword',\r
-       'EDITPANEL': 'keyword',\r
-       'EFFECT': 'keyword',\r
-       'FE_DATA': 'keyword',\r
-       'FE_TABLE': 'keyword',\r
-       'FEData': 'keyword',\r
-       'FILE': 'keyword',\r
-       'FORM': 'keyword',\r
-       'FRAME': 'keyword',\r
-       'FRAMESET': 'keyword',\r
-       'GIFBUILDER': 'keyword',\r
-       'global': 'keyword',\r
-       'globalString': 'keyword',\r
-       'globalVar': 'keyword',\r
-       'GMENU': 'keyword',\r
-       'GMENU_FOLDOUT': 'keyword',\r
-       'GMENU_LAYERS': 'keyword',\r
-       'GP': 'keyword',\r
-       'HMENU': 'keyword',\r
-       'HRULER': 'keyword',\r
-       'HTML': 'keyword',\r
-       'IENV': 'keyword',\r
-       'IMAGE': 'keyword',\r
-       'IMG_RESOURCE': 'keyword',\r
-       'IMGMENU': 'keyword',\r
-       'IMGMENUITEM': 'keyword',\r
-       'IMGTEXT': 'keyword',\r
-       'INCLUDE_TYPOSCRIPT': 'keyword',\r
-       'includeLibs': 'keyword',\r
-       'JSMENU': 'keyword',\r
-       'JSMENUITEM': 'keyword',\r
-       'LIT': 'keyword',\r
-       'LOAD_REGISTER': 'keyword',\r
-       'META': 'keyword',\r
-       'MULTIMEDIA': 'keyword',\r
-       'OTABLE': 'keyword',\r
-       'PAGE': 'keyword',\r
-       'PAGE_TARGET': 'keyword',\r
-       'PAGE_TSCONFIG_ID': 'keyword',\r
-       'PAGE_TSCONFIG_IDLIST': 'keyword',\r
-       'PAGE_TSCONFIG_STR': 'keyword',\r
-       'PHP_SCRIPT': 'keyword',\r
-       'PHP_SCRIPT_EXT': 'keyword',\r
-       'PHP_SCRIPT_INT': 'keyword',\r
-       'RECORDS': 'keyword',\r
-       'REMOTE_ADDR': 'keyword',\r
-       'RESTORE_REGISTER': 'keyword',\r
-       'RTE': 'keyword',\r
-       'SEARCHRESULT': 'keyword',\r
-       'SHARED': 'keyword',\r
-       'TCAdefaults': 'keyword',\r
-       'TCEFORM': 'keyword',\r
-       'TCEMAIN': 'keyword',\r
-       'TEMPLATE': 'keyword',\r
-       'TEXT': 'keyword',\r
-       'TMENU': 'keyword',\r
-       'TMENU_LAYERS': 'keyword',\r
-       'TMENUITEM': 'keyword',\r
-       'TSFE': 'keyword',\r
-       'USER': 'keyword',\r
-       'USER_INT': 'keyword',\r
-       \r
-       'userFunc': 'keyword',\r
-\r
-       '_offset': 'reserved',\r
-       'absRefPrefix': 'reserved',\r
-       'accessibility': 'reserved',\r
-       'accessKey': 'reserved',\r
-       'addAttributes': 'reserved',\r
-       'addExtUrlsAndShortCuts': 'reserved',\r
-       'addItems': 'reserved',\r
-       'additionalHeaders': 'reserved',\r
-       'additionalParams': 'reserved',\r
-       'addParams': 'reserved',\r
-       'addQueryString': 'reserved',\r
-       'adjustItemsH': 'reserved',\r
-       'adjustSubItemsH': 'reserved',\r
-       'adminPanelStyles': 'reserved',\r
-       'after': 'reserved',\r
-       'afterImg': 'reserved',\r
-       'afterImgLink': 'reserved',\r
-       'afterImgTagParams': 'reserved',\r
-       'afterROImg': 'reserved',\r
-       'afterWrap': 'reserved',\r
-       'age': 'reserved',\r
-       'alertPopups': 'reserved',\r
-       'align': 'reserved',\r
-       'allow': 'reserved',\r
-       'allowCaching': 'reserved',\r
-       'allowedAttribs': 'reserved',\r
-       'allowedClasses': 'reserved',\r
-       'allowedCols': 'reserved',\r
-       'allowEdit': 'reserved',\r
-       'allowedNewTables': 'reserved',\r
-       'allowNew': 'reserved',\r
-       'allowTags': 'reserved',\r
-       'allowTVlisting': 'reserved',\r
-       'allSaveFunctions': 'reserved',\r
-       'allStdWrap': 'reserved',\r
-       'allWrap': 'reserved',\r
-       'alternateBgColors': 'reserved',\r
-       'alternativeSortingField': 'reserved',\r
-       'alternativeTempPath': 'reserved',\r
-       'altImgResource': 'reserved',\r
-       'altLabels': 'reserved',\r
-       'altTarget': 'reserved',\r
-       'altText': 'reserved',\r
-       'altUrl': 'reserved',\r
-       'altUrl_noDefaultParams': 'reserved',\r
-       'altWrap': 'reserved',\r
-       'always': 'reserved',\r
-       'alwaysActivePIDlist': 'reserved',\r
-       'alwaysLink': 'reserved',\r
-       'alwaysShowClickMenuInTopFrame': 'reserved',\r
-       'andWhere': 'reserved',\r
-       'angle': 'reserved',\r
-       'antiAlias': 'reserved',\r
-       'append': 'reserved',\r
-       'applyTotalH': 'reserved',\r
-       'applyTotalW': 'reserved',\r
-       'archive': 'reserved',\r
-       'archiveTypoLink': 'reserved',\r
-       'arrayReturnMode': 'reserved',\r
-       'arrowACT': 'reserved',\r
-       'arrowImgParams': 'reserved',\r
-       'arrowNO': 'reserved',\r
-       'ATagAfterWrap': 'reserved',\r
-       'ATagBeforeWrap': 'reserved',\r
-       'ATagParams': 'reserved',\r
-       'ATagTitle': 'reserved',\r
-       'attribute': 'reserved',\r
-       'autoInsertPID': 'reserved',\r
-       'autoLevels': 'reserved',\r
-       'autonumber': 'reserved',\r
-       'backColor': 'reserved',\r
-       'background': 'reserved',\r
-       'badMess': 'reserved',\r
-       'baseURL': 'reserved',\r
-       'before': 'reserved',\r
-       'beforeImg': 'reserved',\r
-       'beforeImgLink': 'reserved',\r
-       'beforeImgTagParams': 'reserved',\r
-       'beforeROImg': 'reserved',\r
-       'beforeWrap': 'reserved',\r
-       'begin': 'reserved',\r
-       'beLoginLinkIPList': 'reserved',\r
-       'beLoginLinkIPList_login': 'reserved',\r
-       'beLoginLinkIPList_logout': 'reserved',\r
-       'bgCol': 'reserved',\r
-       'bgImg': 'reserved',\r
-       'blankStrEqFalse': 'reserved',\r
-       'blur': 'reserved',\r
-       'bm': 'reserved',\r
-       'bodyTag': 'reserved',\r
-       'bodyTagAdd': 'reserved',\r
-       'bodyTagCObject': 'reserved',\r
-       'bodyTagMargins': 'reserved',\r
-       'bodytext': 'reserved',\r
-       'border': 'reserved',\r
-       'borderCol': 'reserved',\r
-       'bordersWithin': 'reserved',\r
-       'borderThick': 'reserved',\r
-       'bottomBackColor': 'reserved',\r
-       'bottomContent': 'reserved',\r
-       'bottomHeight': 'reserved',\r
-       'bottomImg': 'reserved',\r
-       'bottomImg_mask': 'reserved',\r
-       'br': 'reserved',\r
-       'brTag': 'reserved',\r
-       'bullet': 'reserved',\r
-       'bulletlist': 'reserved',\r
-       'bytes': 'reserved',\r
-       'cache_clearAtMidnight': 'reserved',\r
-       'cache_period': 'reserved',\r
-       'caption': 'reserved',\r
-       'caption_stdWrap': 'reserved',\r
-       'captionAlign': 'reserved',\r
-       'captionHeader': 'reserved',\r
-       'captionSplit': 'reserved',\r
-       'case': 'reserved',\r
-       'casesensitiveComp': 'reserved',\r
-       'cellpadding': 'reserved',\r
-       'cellspacing': 'reserved',\r
-       'centerImgACT': 'reserved',\r
-       'centerImgCUR': 'reserved',\r
-       'centerImgNO': 'reserved',\r
-       'centerLeftImgACT': 'reserved',\r
-       'centerLeftImgCUR': 'reserved',\r
-       'centerLeftImgNO': 'reserved',\r
-       'centerRightImgACT': 'reserved',\r
-       'centerRightImgCUR': 'reserved',\r
-       'centerRightImgNO': 'reserved',\r
-       'char': 'reserved',\r
-       'charcoal': 'reserved',\r
-       'charMapConfig': 'reserved',\r
-       'check': 'reserved',\r
-       'class': 'reserved',\r
-       'classesAnchor': 'reserved',\r
-       'classesCharacter': 'reserved',\r
-       'classesImage': 'reserved',\r
-       'classesParagraph': 'reserved',\r
-       'classicPageEditMode': 'reserved',\r
-       'clear': 'reserved',\r
-       'clearCache': 'reserved',\r
-       'clearCache_disable': 'reserved',\r
-       'clearCache_pageGrandParent': 'reserved',\r
-       'clearCache_pageSiblingChildren': 'reserved',\r
-       'clearCacheCmd': 'reserved',\r
-       'clearCacheLevels': 'reserved',\r
-       'clearCacheOfPages': 'reserved',\r
-       'clickMenuTimeOut': 'reserved',\r
-       'clickTitleMode': 'reserved',\r
-       'clipboardNumberPads': 'reserved',\r
-       'cMargins': 'reserved',\r
-       'cObjNum': 'reserved',\r
-       'collapse': 'reserved',\r
-       'color': 'reserved',\r
-       'color1': 'reserved',\r
-       'color2': 'reserved',\r
-       'color3': 'reserved',\r
-       'color4': 'reserved',\r
-       'colors': 'reserved',\r
-       'colour': 'reserved',\r
-       'colPos_list': 'reserved',\r
-       'colRelations': 'reserved',\r
-       'cols': 'reserved',\r
-       'colSpace': 'reserved',\r
-       'comment_auto': 'reserved',\r
-       'commentWrap': 'reserved',\r
-       'compensateFieldWidth': 'reserved',\r
-       'compX': 'reserved',\r
-       'compY': 'reserved',\r
-       'condensedMode': 'reserved',\r
-       'conf': 'reserved',\r
-       'constants': 'reserved',\r
-       'content_from_pid_allowOutsideDomain': 'reserved',\r
-       'contextMenu': 'reserved',\r
-       'copyLevels': 'reserved',\r
-       'count_HMENU_MENUOBJ': 'reserved',\r
-       'count_menuItems': 'reserved',\r
-       'count_MENUOBJ': 'reserved',\r
-       'create': 'reserved',\r
-       'createFoldersInEB': 'reserved',\r
-       'crop': 'reserved',\r
-       'csConv': 'reserved',\r
-       'CSS_inlineStyle': 'reserved',\r
-       'current': 'reserved',\r
-       'curUid': 'reserved',\r
-       'cWidth': 'reserved',\r
-       'data': 'reserved',\r
-       'dataWrap': 'reserved',\r
-       'date': 'reserved',\r
-       'date_stdWrap': 'reserved',\r
-       'datePrefix': 'reserved',\r
-       'debug': 'reserved',\r
-       'debugData': 'reserved',\r
-       'debugFunc': 'reserved',\r
-       'debugItemConf': 'reserved',\r
-       'debugRenumberedObject': 'reserved',\r
-       'default': 'reserved',\r
-       'defaultAlign': 'reserved',\r
-       'defaultCmd': 'reserved',\r
-       'defaultFileUploads': 'reserved',\r
-       'defaultHeaderType': 'reserved',\r
-       'defaultOutput': 'reserved',\r
-       'defaults': 'reserved',\r
-       'defaultType': 'reserved',\r
-       'delete': 'reserved',\r
-       'denyTags': 'reserved',\r
-       'depth': 'reserved',\r
-       'DESC': 'reserved',\r
-       'dimensions': 'reserved',\r
-       'directionLeft': 'reserved',\r
-       'directionUp': 'reserved',\r
-       'disableAdvanced': 'reserved',\r
-       'disableAllHeaderCode': 'reserved',\r
-       'disableAltText': 'reserved',\r
-       'disableBigButtons': 'reserved',\r
-       'disableCacheSelector': 'reserved',\r
-       'disableCharsetHeader': 'reserved',\r
-       'disableCMlayers': 'reserved',\r
-       'disabled': 'reserved',\r
-       'disableDelete': 'reserved',\r
-       'disableDocModuleInAB': 'reserved',\r
-       'disableDocSelector': 'reserved',\r
-       'disableHideAtCopy': 'reserved',\r
-       'disableIconLinkToContextmenu': 'reserved',\r
-       'disableItems': 'reserved',\r
-       'disableNewContentElementWizard': 'reserved',\r
-       'disableNoMatchingValueElement': 'reserved',\r
-       'disablePageExternalUrl': 'reserved',\r
-       'disablePrefixComment': 'reserved',\r
-       'disablePrependAtCopy': 'reserved',\r
-       'disableSearchBox': 'reserved',\r
-       'disableSingleTableView': 'reserved',\r
-       'disableTabInTextarea': 'reserved',\r
-       'displayActiveOnLoad': 'reserved',\r
-       'displayContent': 'reserved',\r
-       'displayFieldIcons': 'reserved',\r
-       'displayIcons': 'reserved',\r
-       'displayMessages': 'reserved',\r
-       'displayQueries': 'reserved',\r
-       'displayRecord': 'reserved',\r
-       'displayTimes': 'reserved',\r
-       'distributeX': 'reserved',\r
-       'distributeY': 'reserved',\r
-       'DIV': 'reserved',\r
-       'doctype': 'reserved',\r
-       'doctypeSwitch': 'reserved',\r
-       'doktype': 'reserved',\r
-       'doNotLinkIt': 'reserved',\r
-       'doNotShowLink': 'reserved',\r
-       'doNotStripHTML': 'reserved',\r
-       'dontCheckPid': 'reserved',\r
-       'dontFollowMouse': 'reserved',\r
-       'dontHideOnMouseUp': 'reserved',\r
-       'dontLinkIfSubmenu': 'reserved',\r
-       'dontShowPalettesOnFocusInAB': 'reserved',\r
-       'dontWrapInTable': 'reserved',\r
-       'doubleBrTag': 'reserved',\r
-       'doublePostCheck': 'reserved',\r
-       'dWorkArea': 'reserved',\r
-       'edge': 'reserved',\r
-       'edit_docModuleUplaod': 'reserved',\r
-       'edit_docModuleUpload': 'reserved',\r
-       'edit_RTE': 'reserved',\r
-       'edit_showFieldHelp': 'reserved',\r
-       'edit_wideDocument': 'reserved',\r
-       'editFieldsAtATime': 'reserved',\r
-       'editFormsOnPage': 'reserved',\r
-       'editIcons': 'reserved',\r
-       'editNoPopup': 'reserved',\r
-       'editPanel': 'reserved',\r
-       'elements': 'reserved',\r
-       'emailMeAtLogin': 'reserved',\r
-       'emailMess': 'reserved',\r
-       'emboss': 'reserved',\r
-       'enable': 'reserved',\r
-       'encapsLines': 'reserved',\r
-       'encapsLinesStdWrap': 'reserved',\r
-       'encapsTagList': 'reserved',\r
-       'entryLevel': 'reserved',\r
-       'equalH': 'reserved',\r
-       'everybody': 'reserved',\r
-       'excludeDoktypes': 'reserved',\r
-       'excludeUidList': 'reserved',\r
-       'expAll': 'reserved',\r
-       'expand': 'reserved',\r
-       'explode': 'reserved',\r
-       'ext': 'reserved',\r
-       'externalBlocks': 'reserved',\r
-       'extTarget': 'reserved',\r
-       'face': 'reserved',\r
-       'fe_adminLib': 'reserved',\r
-       'field': 'reserved',\r
-       'fieldOrder': 'reserved',\r
-       'fieldRequired': 'reserved',\r
-       'fields': 'reserved',\r
-       'fieldWrap': 'reserved',\r
-       'file': 'reserved',\r
-       'file1': 'reserved',\r
-       'file2': 'reserved',\r
-       'file3': 'reserved',\r
-       'file4': 'reserved',\r
-       'file5': 'reserved',\r
-       'filelink': 'reserved',\r
-       'filelist': 'reserved',\r
-       'firstLabel': 'reserved',\r
-       'firstLabelGeneral': 'reserved',\r
-       'fixAttrib': 'reserved',\r
-       'flip': 'reserved',\r
-       'flop': 'reserved',\r
-       'foldSpeed': 'reserved',\r
-       'foldTimer': 'reserved',\r
-       'fontColor': 'reserved',\r
-       'fontFile': 'reserved',\r
-       'fontOffset': 'reserved',\r
-       'fontSize': 'reserved',\r
-       'fontSizeMultiplicator': 'reserved',\r
-       'fontTag': 'reserved',\r
-       'forceDisplayFieldIcons': 'reserved',\r
-       'forceDisplayIcons': 'reserved',\r
-       'forceNoPopup': 'reserved',\r
-       'forceTemplateParsing': 'reserved',\r
-       'forceTypeValue': 'reserved',\r
-       'format': 'reserved',\r
-       'frame': 'reserved',\r
-       'frameReloadIfNotInFrameset': 'reserved',\r
-       'frameSet': 'reserved',\r
-       'freezeMouseover': 'reserved',\r
-       'ftu': 'reserved',\r
-       'function': 'reserved',\r
-       'gamma': 'reserved',\r
-       'gapBgCol': 'reserved',\r
-       'gapLineCol': 'reserved',\r
-       'gapLineThickness': 'reserved',\r
-       'gapWidth': 'reserved',\r
-       'get': 'reserved',\r
-       'getBorder': 'reserved',\r
-       'getLeft': 'reserved',\r
-       'getRight': 'reserved',\r
-       'globalNesting': 'reserved',\r
-       'goodMess': 'reserved',\r
-       'gray': 'reserved',\r
-       'group': 'reserved',\r
-       'groupBy': 'reserved',\r
-       'groupid': 'reserved',\r
-       'header': 'reserved',\r
-       'header_layout': 'reserved',\r
-       'headerComment': 'reserved',\r
-       'headerData': 'reserved',\r
-       'headerSpace': 'reserved',\r
-       'headTag': 'reserved',\r
-       'height': 'reserved',\r
-       'helpText': 'reserved',\r
-       'hidden': 'reserved',\r
-       'hiddenFields': 'reserved',\r
-       'hide': 'reserved',\r
-       'hideButCreateMap': 'reserved',\r
-       'hideMenuTimer': 'reserved',\r
-       'hideMenuWhenNotOver': 'reserved',\r
-       'hidePStyleItems': 'reserved',\r
-       'hideRecords': 'reserved',\r
-       'hideSubmoduleIcons': 'reserved',\r
-       'highColor': 'reserved',\r
-       'history': 'reserved',\r
-       'hover': 'reserved',\r
-       'hoverStyle': 'reserved',\r
-       'HTMLparser': 'reserved',\r
-       'HTMLparser_tags': 'reserved',\r
-       'htmlSpecialChars': 'reserved',\r
-       'htmlTag_dir': 'reserved',\r
-       'htmlTag_langKey': 'reserved',\r
-       'htmlTag_setParams': 'reserved',\r
-       'http': 'reserved',\r
-       'icon': 'reserved',\r
-       'icon_image_ext_list': 'reserved',\r
-       'icon_link': 'reserved',\r
-       'iconCObject': 'reserved',\r
-       'ifEmpty': 'reserved',\r
-       'image': 'reserved',\r
-       'image_compression': 'reserved',\r
-       'image_effects': 'reserved',\r
-       'image_frames': 'reserved',\r
-       'imageLinkWrap': 'reserved',\r
-       'imagePath': 'reserved',\r
-       'images': 'reserved',\r
-       'imageWrapIfAny': 'reserved',\r
-       'imgList': 'reserved',\r
-       'imgMap': 'reserved',\r
-       'imgMapExtras': 'reserved',\r
-       'imgMax': 'reserved',\r
-       'imgNameNotRandom': 'reserved',\r
-       'imgNamePrefix': 'reserved',\r
-       'imgObjNum': 'reserved',\r
-       'imgParams': 'reserved',\r
-       'imgPath': 'reserved',\r
-       'imgStart': 'reserved',\r
-       'import': 'reserved',\r
-       'inc': 'reserved',\r
-       'includeCSS': 'reserved',\r
-       'includeLibrary': 'reserved',\r
-       'includeNotInMenu': 'reserved',\r
-       'incT3Lib_htmlmail': 'reserved',\r
-       'index': 'reserved',\r
-       'index_descrLgd': 'reserved',\r
-       'index_enable': 'reserved',\r
-       'index_externals': 'reserved',\r
-       'inlineStyle2TempFile': 'reserved',\r
-       'innerStdWrap': 'reserved',\r
-       'innerStdWrap_all': 'reserved',\r
-       'innerWrap': 'reserved',\r
-       'innerWrap2': 'reserved',\r
-       'input': 'reserved',\r
-       'inputLevels': 'reserved',\r
-       'insertClassesFromRTE': 'reserved',\r
-       'insertData': 'reserved',\r
-       'insertDmailerBoundaries': 'reserved',\r
-       'intensity': 'reserved',\r
-       'intTarget': 'reserved',\r
-       'intval': 'reserved',\r
-       'invert': 'reserved',\r
-       'IProcFunc': 'reserved',\r
-       'itemArrayProcFunc': 'reserved',\r
-       'itemH': 'reserved',\r
-       'items': 'reserved',\r
-       'itemsProcFunc': 'reserved',\r
-       'iterations': 'reserved',\r
-       'join': 'reserved',\r
-       'JSWindow': 'reserved',\r
-       'JSwindow_params': 'reserved',\r
-       'jumpurl': 'reserved',\r
-       'jumpUrl': 'reserved',\r
-       'jumpurl_enable': 'reserved',\r
-       'jumpurl_mailto_disable': 'reserved',\r
-       'jumpUrl_transferSession': 'reserved',\r
-       'keep': 'reserved',\r
-       'keepEntries': 'reserved',\r
-       'keepNonMatchedTags': 'reserved',\r
-       'key': 'reserved',\r
-       'label': 'reserved',\r
-       'labelStdWrap': 'reserved',\r
-       'labelWrap': 'reserved',\r
-       'lang': 'reserved',\r
-       'language': 'reserved',\r
-       'language_alt': 'reserved',\r
-       'languageField': 'reserved',\r
-       'layer_menu_id': 'reserved',\r
-       'layerStyle': 'reserved',\r
-       'left': 'reserved',\r
-       'leftIcons': 'reserved',\r
-       'leftImgACT': 'reserved',\r
-       'leftImgCUR': 'reserved',\r
-       'leftImgNO': 'reserved',\r
-       'leftjoin': 'reserved',\r
-       'leftOffset': 'reserved',\r
-       'levels': 'reserved',\r
-       'leveluid': 'reserved',\r
-       'limit': 'reserved',\r
-       'line': 'reserved',\r
-       'lineColor': 'reserved',\r
-       'lineThickness': 'reserved',\r
-       'linkPrefix': 'reserved',\r
-       'linkTitleToSelf': 'reserved',\r
-       'linkVars': 'reserved',\r
-       'linkWrap': 'reserved',\r
-       'listNum': 'reserved',\r
-       'listOnlyInSingleTableView': 'reserved',\r
-       'lm': 'reserved',\r
-       'locale_all': 'reserved',\r
-       'localNesting': 'reserved',\r
-       'locationData': 'reserved',\r
-       'lockFilePath': 'reserved',\r
-       'lockPosition': 'reserved',\r
-       'lockPosition_addSelf': 'reserved',\r
-       'lockPosition_adjust': 'reserved',\r
-       'lockToIP': 'reserved',\r
-       'longdescURL': 'reserved',\r
-       'lowColor': 'reserved',\r
-       'lower': 'reserved',\r
-       'LR': 'reserved',\r
-       'mailto': 'reserved',\r
-       'main': 'reserved',\r
-       'mainScript': 'reserved',\r
-       'makelinks': 'reserved',\r
-       'markerWrap': 'reserved',\r
-       'mask': 'reserved',\r
-       'max': 'reserved',\r
-       'maxAge': 'reserved',\r
-       'maxAgeDays': 'reserved',\r
-       'maxChars': 'reserved',\r
-       'maxH': 'reserved',\r
-       'maxHeight': 'reserved',\r
-       'maxItems': 'reserved',\r
-       'maxW': 'reserved',\r
-       'maxWidth': 'reserved',\r
-       'maxWInText': 'reserved',\r
-       'mayNotCreateEditShortcuts': 'reserved',\r
-       'menu_type': 'reserved',\r
-       'menuBackColor': 'reserved',\r
-       'menuHeight': 'reserved',\r
-       'menuName': 'reserved',\r
-       'menuOffset': 'reserved',\r
-       'menuWidth': 'reserved',\r
-       'message_page_is_being_generated': 'reserved',\r
-       'message_preview': 'reserved',\r
-       'meta': 'reserved',\r
-       'metaCharset': 'reserved',\r
-       'method': 'reserved',\r
-       'min': 'reserved',\r
-       'minH': 'reserved',\r
-       'minItems': 'reserved',\r
-       'minW': 'reserved',\r
-       'mode': 'reserved',\r
-       'moduleMenuCollapsable': 'reserved',\r
-       'MP_defaults': 'reserved',\r
-       'MP_disableTypolinkClosestMPvalue': 'reserved',\r
-       'MP_mapRootPoints': 'reserved',\r
-       'name': 'reserved',\r
-       'navFrameResizable': 'reserved',\r
-       'navFrameWidth': 'reserved',\r
-       'nesting': 'reserved',\r
-       'netprintApplicationLink': 'reserved',\r
-       'neverHideAtCopy': 'reserved',\r
-       'newPageWiz': 'reserved',\r
-       'newRecordFromTable': 'reserved',\r
-       'newWindow': 'reserved',\r
-       'newWizards': 'reserved',\r
-       'next': 'reserved',\r
-       'niceText': 'reserved',\r
-       'nicetext': 'reserved',\r
-       'no_cache': 'reserved',\r
-       'no_search': 'reserved',\r
-       'noAttrib': 'reserved',\r
-       'noBlur': 'reserved',\r
-       'noCache': 'reserved',\r
-       'noCols': 'reserved',\r
-       'noCreateRecordsLink': 'reserved',\r
-       'noLink': 'reserved',\r
-       'noLinkUnderline': 'reserved',\r
-       'noMatchingValue_label': 'reserved',\r
-       'noMenuMode': 'reserved',\r
-       'nonCachedSubst': 'reserved',\r
-       'nonTypoTagStdWrap': 'reserved',\r
-       'nonTypoTagUserFunc': 'reserved',\r
-       'nonWrappedTag': 'reserved',\r
-       'noOrderBy': 'reserved',\r
-       'noPageTitle': 'reserved',\r
-       'noRows': 'reserved',\r
-       'noScaleUp': 'reserved',\r
-       'noStretchAndMarginCells': 'reserved',\r
-       'noThumbsInEB': 'reserved',\r
-       'noThumbsInRTEimageSelect': 'reserved',\r
-       'notification_email_charset': 'reserved',\r
-       'notification_email_encoding': 'reserved',\r
-       'notification_email_urlmode': 'reserved',\r
-       'noTrimWrap': 'reserved',\r
-       'noValueInsert': 'reserved',\r
-       'obj': 'reserved',\r
-       'offset': 'reserved',\r
-       'offsetWrap': 'reserved',\r
-       'onlineWorkspaceInfo': 'reserved',\r
-       'onlyCurrentPid': 'reserved',\r
-       'opacity': 'reserved',\r
-       'orderBy': 'reserved',\r
-       'outerWrap': 'reserved',\r
-       'outline': 'reserved',\r
-       'outputLevels': 'reserved',\r
-       'override': 'reserved',\r
-       'overrideAttribs': 'reserved',\r
-       'overrideEdit': 'reserved',\r
-       'overrideId': 'reserved',\r
-       'overridePageModule': 'reserved',\r
-       'overrideWithExtension': 'reserved',\r
-       'pageFrameObj': 'reserved',\r
-       'pageGenScript': 'reserved',\r
-       'pageTitleFirst': 'reserved',\r
-       'parameter': 'reserved',\r
-       'params': 'reserved',\r
-       'parseFunc': 'reserved',\r
-       'parser': 'reserved',\r
-       'password': 'reserved',\r
-       'path': 'reserved',\r
-       'permissions': 'reserved',\r
-       'pid_list': 'reserved',\r
-       'pidInList': 'reserved',\r
-       'pixelSpaceFontSizeRef': 'reserved',\r
-       'plaintextLib': 'reserved',\r
-       'plainTextStdWrap': 'reserved',\r
-       'postCObject': 'reserved',\r
-       'postLineBlanks': 'reserved',\r
-       'postLineChar': 'reserved',\r
-       'postLineLen': 'reserved',\r
-       'postUserFunc': 'reserved',\r
-       'postUserFuncInt': 'reserved',\r
-       'preBlanks': 'reserved',\r
-       'preCObject': 'reserved',\r
-       'prefix': 'reserved',\r
-       'prefixComment': 'reserved',\r
-       'prefixLocalAnchors': 'reserved',\r
-       'prefixRelPathWith': 'reserved',\r
-       'preIfEmptyListNum': 'reserved',\r
-       'preLineBlanks': 'reserved',\r
-       'preLineChar': 'reserved',\r
-       'preLineLen': 'reserved',\r
-       'prepend': 'reserved',\r
-       'preserveEntities': 'reserved',\r
-       'preUserFunc': 'reserved',\r
-       'prev': 'reserved',\r
-       'previewBorder': 'reserved',\r
-       'prevnextToSection': 'reserved',\r
-       'printheader': 'reserved',\r
-       'prioriCalc': 'reserved',\r
-       'proc': 'reserved',\r
-       'processScript': 'reserved',\r
-       'properties': 'reserved',\r
-       'protect': 'reserved',\r
-       'protectLvar': 'reserved',\r
-       'publish_levels': 'reserved',\r
-       'QEisDefault': 'reserved',\r
-       'quality': 'reserved',\r
-       'radio': 'reserved',\r
-       'radioWrap': 'reserved',\r
-       'range': 'reserved',\r
-       'rawUrlEncode': 'reserved',\r
-       'recipient': 'reserved',\r
-       'recursive': 'reserved',\r
-       'recursiveDelete': 'reserved',\r
-       'redirect': 'reserved',\r
-       'redirectToURL': 'reserved',\r
-       'reduceColors': 'reserved',\r
-       'register': 'reserved',\r
-       'relativeToParentLayer': 'reserved',\r
-       'relativeToTriggerItem': 'reserved',\r
-       'relPathPrefix': 'reserved',\r
-       'remap': 'reserved',\r
-       'remapTag': 'reserved',\r
-       'removeBadHTML': 'reserved',\r
-       'removeDefaultJS': 'reserved',\r
-       'removeIfEquals': 'reserved',\r
-       'removeIfFalse': 'reserved',\r
-       'removeItems': 'reserved',\r
-       'removeObjectsOfDummy': 'reserved',\r
-       'removePrependedNumbers': 'reserved',\r
-       'removeTags': 'reserved',\r
-       'removeWrapping': 'reserved',\r
-       'renderCharset': 'reserved',\r
-       'renderWrap': 'reserved',\r
-       'reset': 'reserved',\r
-       'resources': 'reserved',\r
-       'resultObj': 'reserved',\r
-       'returnLast': 'reserved',\r
-       'returnUrl': 'reserved',\r
-       'rightImgACT': 'reserved',\r
-       'rightImgCUR': 'reserved',\r
-       'rightImgNO': 'reserved',\r
-       'rightjoin': 'reserved',\r
-       'rm': 'reserved',\r
-       'rmTagIfNoAttrib': 'reserved',\r
-       'RO_chBgColor': 'reserved',\r
-       'rotate': 'reserved',\r
-       'rows': 'reserved',\r
-       'rowSpace': 'reserved',\r
-       'RTEfullScreenWidth': 'reserved',\r
-       'rules': 'reserved',\r
-       'sample': 'reserved',\r
-       'saveClipboard': 'reserved',\r
-       'saveDocNew': 'reserved',\r
-       'secondRow': 'reserved',\r
-       'section': 'reserved',\r
-       'sectionIndex': 'reserved',\r
-       'select': 'reserved',\r
-       'select_key': 'reserved',\r
-       'selectFields': 'reserved',\r
-       'separator': 'reserved',\r
-       'set': 'reserved',\r
-       'setContentToCurrent': 'reserved',\r
-       'setCurrent': 'reserved',\r
-       'setfixed': 'reserved',\r
-       'setFixedHeight': 'reserved',\r
-       'setFixedWidth': 'reserved',\r
-       'setJS_mouseOver': 'reserved',\r
-       'setJS_openPic': 'reserved',\r
-       'setOnly': 'reserved',\r
-       'shadow': 'reserved',\r
-       'sharpen': 'reserved',\r
-       'shear': 'reserved',\r
-       'short': 'reserved',\r
-       'shortcut': 'reserved',\r
-       'shortcut_onEditId_dontSetPageTree': 'reserved',\r
-       'shortcut_onEditId_keepExistingExpanded': 'reserved',\r
-       'shortcutFrame': 'reserved',\r
-       'shortcutGroups': 'reserved',\r
-       'shortcutIcon': 'reserved',\r
-       'show': 'reserved',\r
-       'showAccessRestrictedPages': 'reserved',\r
-       'showActive': 'reserved',\r
-       'showClipControlPanelsDespiteOfCMlayers': 'reserved',\r
-       'showFirst': 'reserved',\r
-       'showHiddenPages': 'reserved',\r
-       'showHiddenRecords': 'reserved',\r
-       'showHistory': 'reserved',\r
-       'showPageIdWithTitle': 'reserved',\r
-       'showTagFreeClasses': 'reserved',\r
-       'simulateDate': 'reserved',\r
-       'simulateStaticDocuments': 'reserved',\r
-       'simulateStaticDocuments_addTitle': 'reserved',\r
-       'simulateStaticDocuments_dontRedirectPathInfoError': 'reserved',\r
-       'simulateStaticDocuments_noTypeIfNoTitle': 'reserved',\r
-       'simulateStaticDocuments_pEnc': 'reserved',\r
-       'simulateStaticDocuments_pEnc_onlyP': 'reserved',\r
-       'simulateUserGroup': 'reserved',\r
-       'singlePid': 'reserved',\r
-       'site_author': 'reserved',\r
-       'site_reserved': 'reserved',\r
-       'sitetitle': 'reserved',\r
-       'siteUrl': 'reserved',\r
-       'size': 'reserved',\r
-       'smallFormFields': 'reserved',\r
-       'solarize': 'reserved',\r
-       'sorting': 'reserved',\r
-       'source': 'reserved',\r
-       'space': 'reserved',\r
-       'spaceAfter': 'reserved',\r
-       'spaceBefore': 'reserved',\r
-       'spaceBelowAbove': 'reserved',\r
-       'spaceLeft': 'reserved',\r
-       'spaceRight': 'reserved',\r
-       'spacing': 'reserved',\r
-       'spamProtectEmailAddresses': 'reserved',\r
-       'spamProtectEmailAddresses_atSubst': 'reserved',\r
-       'spamProtectEmailAddresses_lastDotSubst': 'reserved',\r
-       'special': 'reserved',\r
-       'splitChar': 'reserved',\r
-       'splitRendering': 'reserved',\r
-       'src': 'reserved',\r
-       'startInTaskCenter': 'reserved',\r
-       'stayFolded': 'reserved',\r
-       'stdheader': 'reserved',\r
-       'stdWrap': 'reserved',\r
-       'stdWrap2': 'reserved',\r
-       'strftime': 'reserved',\r
-       'stripHtml': 'reserved',\r
-       'styles': 'reserved',\r
-       'stylesheet': 'reserved',\r
-       'submenuObjSuffixes': 'reserved',\r
-       'subMenuOffset': 'reserved',\r
-       'submit': 'reserved',\r
-       'subst_elementUid': 'reserved',\r
-       'substMarksSeparately': 'reserved',\r
-       'substring': 'reserved',\r
-       'swirl': 'reserved',\r
-       'sword': 'reserved',\r
-       'sword_noMixedCase': 'reserved',\r
-       'SWORD_PARAMS': 'reserved',\r
-       'sword_standAlone': 'reserved',\r
-       'sys_language_mode': 'reserved',\r
-       'sys_language_overlay': 'reserved',\r
-       'sys_language_softMergeIfNotBlank': 'reserved',\r
-       'sys_language_uid': 'reserved',\r
-       'table': 'reserved',\r
-       'tableCellColor': 'reserved',\r
-       'tableParams': 'reserved',\r
-       'tables': 'reserved',\r
-       'tableStdWrap': 'reserved',\r
-       'tableStyle': 'reserved',\r
-       'tableWidth': 'reserved',\r
-       'tags': 'reserved',\r
-       'target': 'reserved',\r
-       'TDparams': 'reserved',\r
-       'templateContent': 'reserved',\r
-       'templateFile': 'reserved',\r
-       'text': 'reserved',\r
-       'textarea': 'reserved',\r
-       'textMargin': 'reserved',\r
-       'textMargin_outOfText': 'reserved',\r
-       'textMaxLength': 'reserved',\r
-       'textObjNum': 'reserved',\r
-       'textPos': 'reserved',\r
-       'textStyle': 'reserved',\r
-       'thickness': 'reserved',\r
-       'thumbnailsByDefault': 'reserved',\r
-       'tile': 'reserved',\r
-       'time_stdWrap': 'reserved',\r
-       'tipafriendLib': 'reserved',\r
-       'title': 'reserved',\r
-       'titleLen': 'reserved',\r
-       'titleTagFunction': 'reserved',\r
-       'titleText': 'reserved',\r
-       'tm': 'reserved',\r
-       'token': 'reserved',\r
-       'topOffset': 'reserved',\r
-       'totalWidth': 'reserved',\r
-       'transparentBackground': 'reserved',\r
-       'transparentColor': 'reserved',\r
-       'trim': 'reserved',\r
-       'tsdebug_tree': 'reserved',\r
-       'type': 'reserved',\r
-       'typeNum': 'reserved',\r
-       'types': 'reserved',\r
-       'typolinkCheckRootline': 'reserved',\r
-       'uidInList': 'reserved',\r
-       'unset': 'reserved',\r
-       'uploadFieldsInTopOfEB': 'reserved',\r
-       'uploads': 'reserved',\r
-       'upper': 'reserved',\r
-       'useCacheHash': 'reserved',\r
-       'useLargestItemX': 'reserved',\r
-       'useLargestItemY': 'reserved',\r
-       'user': 'reserved',\r
-       'userdefined': 'reserved',\r
-       'userfunction': 'reserved',\r
-       'userid': 'reserved',\r
-       'userIdColumn': 'reserved',\r
-       'USERNAME_substToken': 'reserved',\r
-       'userProc': 'reserved',\r
-       'value': 'reserved',\r
-       'valueArray': 'reserved',\r
-       'wave': 'reserved',\r
-       'where': 'reserved',\r
-       'width': 'reserved',\r
-       'wiz': 'reserved',\r
-       'wordSpacing': 'reserved',\r
-       'workArea': 'reserved',\r
-       'wrap': 'reserved',\r
-       'wrap1': 'reserved',\r
-       'wrap2': 'reserved',\r
-       'wrap3': 'reserved',\r
-       'wrapAfterTags': 'reserved',\r
-       'wrapAlign': 'reserved',\r
-       'wrapFieldName': 'reserved',\r
-       'wrapItemAndSub': 'reserved',\r
-       'wrapNonWrappedLines': 'reserved',\r
-       'wraps': 'reserved',\r
-       'xhtml_cleaning': 'reserved',\r
-       'xmlprologue': 'reserved',\r
-       'xPosOffset': 'reserved',\r
-       'yPosOffset': 'reserved',\r
-\r
-       'admPanel': 'keyword2',\r
-       'alt_print': 'keyword2',\r
-       'auth': 'keyword2',\r
-       'browser': 'keyword2',\r
-       'cache': 'keyword2',\r
-       'CHECK': 'keyword2',\r
-       'cObj': 'keyword2',\r
-       'cObject': 'keyword2',\r
-       'COMMENT': 'keyword2',\r
-       'config': 'keyword2',\r
-       'content': 'keyword2',\r
-       'copy': 'keyword2',\r
-       'CSS_inlineStyle': 'keyword2',\r
-       'cut': 'keyword2',\r
-       'dataArray': 'keyword2',\r
-       'dayofmonth': 'keyword2',\r
-       'dayofweek': 'keyword2',\r
-       'db_list': 'keyword2',\r
-       'device': 'keyword2',\r
-       'dynCSS': 'keyword2',\r
-       'edit': 'keyword2',\r
-       'edit_access': 'keyword2',\r
-       'edit_pageheader': 'keyword2',\r
-       'folder': 'keyword2',\r
-       'folderTree': 'keyword2',\r
-       'foldoutMenu': 'keyword2',\r
-       'Functions': 'keyword2',\r
-       'gmenu_foldout': 'keyword2',\r
-       'gmenu_layers': 'keyword2',\r
-       'hostname': 'keyword2',\r
-       'hour': 'keyword2',\r
-       'imgList': 'keyword2',\r
-       'imgResource': 'keyword2',\r
-       'imgText': 'keyword2',\r
-       'info': 'keyword2',\r
-       'IP': 'keyword2',\r
-       'jsmenu': 'keyword2',\r
-       'JSwindow': 'keyword2',\r
-       'LABEL': 'keyword2',\r
-       'layout': 'keyword2',\r
-       'lib': 'keyword2',\r
-       'loginUser': 'keyword2',\r
-       'marks': 'keyword2',\r
-       'minute': 'keyword2',\r
-       'mod': 'keyword2',\r
-       'module': 'keyword2',\r
-       'month': 'keyword2',\r
-       'move_wizard': 'keyword2',\r
-       'new': 'keyword2',\r
-       'new_wizard': 'keyword2',\r
-       'noResultObj': 'keyword2',\r
-       'numRows': 'keyword2',\r
-       'options': 'keyword2',\r
-       'page': 'keyword2',\r
-       'pageTree': 'keyword2',\r
-       'paste': 'keyword2',\r
-       'perms': 'keyword2',\r
-       'PIDinRootline': 'keyword2',\r
-       'PIDupinRootline': 'keyword2',\r
-       'plugin': 'keyword2',\r
-       'postform': 'keyword2',\r
-       'postform_newThread': 'keyword2',\r
-       'preview': 'keyword2',\r
-       'publish': 'keyword2',\r
-       'RADIO': 'keyword2',\r
-       'renderObj': 'keyword2',\r
-       'REQ': 'keyword2',\r
-       'RTE': 'keyword2',\r
-       'RTE_compliant': 'keyword2',\r
-       'select': 'keyword2',\r
-       'setup': 'keyword2',\r
-       'split': 'keyword2',\r
-       'stat': 'keyword2',\r
-       'stat_apache': 'keyword2',\r
-       'stat_apache_logfile': 'keyword2',\r
-       'stat_apache_noHost': 'keyword2',\r
-       'stat_apache_notExtended': 'keyword2',\r
-       'stat_apache_pagenames': 'keyword2',\r
-       'stat_excludeBEuserHits': 'keyword2',\r
-       'stat_excludeIPList': 'keyword2',\r
-       'stat_mysql': 'keyword2',\r
-       'stat_titleLen': 'keyword2',\r
-       'stat_typeNumList': 'keyword2',\r
-       'stdWrap': 'keyword2',\r
-       'subparts': 'keyword2',\r
-       'system': 'keyword2',\r
-       'temp': 'keyword2',\r
-       'template': 'keyword2',\r
-       'treeLevel': 'keyword2',\r
-       'tsdebug': 'keyword2',\r
-       'typolink': 'keyword2',\r
-       'url': 'keyword2',\r
-       'useragent': 'keyword2',\r
-       'userFunc': 'keyword2',\r
-       'version': 'keyword2',\r
-       'view': 'keyword2',\r
-       'workOnSubpart': 'keyword2',\r
-\r
-       'ACT': 'keyword3',\r
-       'ACTIFSUB': 'keyword3',\r
-       'ACTIFSUBRO': 'keyword',\r
-       'ACTRO': 'keyword3',\r
-       'all': 'keyword3',\r
-       'arrowACT': 'keyword3',\r
-       'arrowNO': 'keyword3',\r
-       'ascii': 'keyword3',\r
-       'atLeast': 'keyword3',\r
-       'atMost': 'keyword3',\r
-       'BE': 'keyword3',\r
-       'be_groups': 'keyword3',\r
-       'be_users': 'keyword3',\r
-       'BOX': 'keyword3',\r
-       'browse': 'keyword3',\r
-       'bullets': 'keyword3',\r
-       'CUR': 'keyword3',\r
-       'CURIFSUB': 'keyword3',\r
-       'CURIFSUBRO': 'keyword3',\r
-       'CURRO': 'keyword3',\r
-       'default': 'keyword3',\r
-       'description': 'keyword3',\r
-       'directory': 'keyword3',\r
-       'directReturn': 'keyword3',\r
-       'div': 'keyword3',\r
-       'else': 'keyword3',\r
-       'email': 'keyword3',\r
-       'end': 'keyword3',\r
-       'equals': 'keyword3',\r
-       'external': 'keyword3',\r
-       'false': 'keyword3',\r
-       'FE': 'keyword3',\r
-       'fe_groups': 'keyword3',\r
-       'fe_users': 'keyword3',\r
-       'feadmin': 'keyword3',\r
-       'header': 'keyword3',\r
-       'html': 'keyword3',\r
-       'id': 'keyword3',\r
-       'if': 'keyword3',\r
-       'ifEmpty': 'keyword3',\r
-       'IFSUB': 'keyword3',\r
-       'IFSUBRO': 'keyword3',\r
-       'image': 'keyword3',\r
-       'inBranch': 'keyword3',\r
-       'isFalse': 'keyword3',\r
-       'isGreaterThan': 'keyword3',\r
-       'isInList': 'keyword3',\r
-       'isLessThan': 'keyword3',\r
-       'isPositive': 'keyword3',\r
-       'isTrue': 'keyword3',\r
-       'keyword3': 'keyword3',\r
-       'language': 'keyword3',\r
-       'leveltitle': 'keyword3',\r
-       'list': 'keyword3',\r
-       'login': 'keyword3',\r
-       'mailform': 'keyword3',\r
-       'media': 'keyword3',\r
-       'menu': 'keyword3',\r
-       'mod': 'keyword3',\r
-       'multimedia': 'keyword3',\r
-       'negate': 'keyword3',\r
-       'NEW': 'keyword3',\r
-       'NO': 'keyword3',\r
-       'none': 'keyword3',\r
-       'pages': 'keyword3',\r
-       'pages_language_overlay': 'keyword3',\r
-       'parseFunc_RTE': 'keyword3',\r
-       'pid': 'keyword3',\r
-       'required': 'keyword3',\r
-       'RO': 'keyword3',\r
-       'rootline': 'keyword3',\r
-       'script': 'keyword3',\r
-       'search': 'keyword3',\r
-       'shortcut': 'keyword3',\r
-       'sitemap': 'keyword3',\r
-       'SPC': 'keyword3',\r
-       'splash': 'keyword3',\r
-       'sys_dmail': 'keyword3',\r
-       'sys_domain': 'keyword3',\r
-       'sys_filemounts': 'keyword3',\r
-       'sys_note': 'keyword3',\r
-       'sys_template': 'keyword3',\r
-       'tabel': 'keyword3',\r
-       'text': 'keyword3',\r
-       'textpic': 'keyword3',\r
-       'this': 'keyword3',\r
-       'top': 'keyword3',\r
-       'true': 'keyword3',\r
-       'twice': 'keyword3',\r
-       'uid': 'keyword3',\r
-       'uniqueGlobal': 'keyword3',\r
-       'uniqueLocal': 'keyword3',\r
-       'unsetEmpty': 'keyword3',\r
-       'updated': 'keyword3',\r
-       'uploads': 'keyword3',\r
-       'us': 'keyword3',\r
-       'user_task': 'keyword3',\r
-       'USERDEF1': 'keyword3',\r
-       'USERDEF1RO': 'keyword3',\r
-       'USERDEF2': 'keyword3',\r
-       'USERDEF2RO': 'keyword3',\r
-       'usergroup': 'keyword3',\r
-       'USR': 'keyword3',\r
-       'USRRO': 'keyword3',\r
-       'web_func': 'keyword3',\r
-       'web_info': 'keyword3',\r
-       'web_layout': 'keyword3',\r
-       'web_list': 'keyword3',\r
-       'web_ts': 'keyword',\r
-       'xhtml_strict': 'keyword3',\r
-       'xhtml_trans': 'keyword3',\r
-       'XY': 'keyword3',\r
-       'ypMenu': 'keyword3'\r
-}\r
-\r
-var tokenizeTypoScript = function() {\r
-\r
-       // Some helper regexp matchers.\r
-       var isOperatorChar = matcher(/[\+\-\*\&\%\/=<>!\?]/);\r
-       var isDigit = matcher(/[0-9]/);\r
-       var isHexDigit = matcher(/[0-9A-Fa-f]/);\r
-       var isWordChar = matcher(/[\w\$_]/);\r
-\r
-       function isWhiteSpace(ch) {\r
-               // Unfortunately, IE's regexp matcher thinks non-breaking spaces\r
-               // aren't whitespace. Also, in our scheme newlines are no\r
-               // whitespace (they are another special case).\r
-               return ch != "\n" && (ch == nbsp || /\s/.test(ch));\r
-       }\r
-\r
-       // This function produces a MochiKit-style iterator that tokenizes\r
-       // the output of the given stringstream (see stringstream.js).\r
-       // Tokens are objects with a type, style, and value property. The\r
-       // value contains the textual content of the token. Because this may\r
-       // include trailing whitespace (for efficiency reasons), some\r
-       // tokens, such a variable names, also have a name property\r
-       // containing their actual textual value.\r
-       return function(source) {\r
-               // Produce a value to return. Automatically skips and includes any\r
-               // whitespace. The base argument is prepended to the value\r
-               // property and assigned to the name property -- this is used when\r
-               // the caller has already extracted the text from the stream\r
-               // himself.\r
-               function result(type, style, base) {\r
-                       // nextWhile(isWhiteSpace); - comment thats line because needed for autocomplete\r
-                       var value = {\r
-                               type: type,\r
-                               style: style,\r
-                               value: (base ? base + source.get() : source.get())\r
-                       };\r
-                       if (base) {\r
-                               value.name = base;\r
-                       }\r
-                       return value;\r
-               }\r
-\r
-               // Advance the text stream over characters for which test returns\r
-               // true. (The characters that are 'consumed' like this can later\r
-               // be retrieved by calling source.get()).\r
-               function nextWhile(test) {\r
-                       var next;\r
-                       while ((next = source.peek()) && test(next)) {\r
-                               source.next();\r
-                       }\r
-               }\r
-\r
-               // Advance the stream until the given character (not preceded by a\r
-               // backslash) is encountered (or a newline is found).\r
-               function nextUntilUnescaped(end) {\r
-                       var escaped = false;\r
-                       var next;\r
-                       while ((next = source.peek()) && next != "\n") {\r
-                               source.next();\r
-                               if (next == end && !escaped) {\r
-                                       break;\r
-                               }\r
-                               escaped = next == "\\";\r
-                       }\r
-               }\r
-\r
-               function readHexNumber() {\r
-                       source.next();\r
-                       // skip the 'x'\r
-                       nextWhile(isHexDigit);\r
-                       return result("number", "atom");\r
-               }\r
-\r
-               function readNumber() {\r
-                       nextWhile(isDigit);\r
-                       return result("number", "atom");\r
-               }\r
-\r
-               // Read a word, look it up in keywords. If not found, it is a\r
-               // variable, otherwise it is a keyword of the type found.\r
-               function readWord() {\r
-                       nextWhile(isWordChar);\r
-                       var word = source.get();\r
-                       var known = typoscriptWords.hasOwnProperty(word) && {\r
-                               type: 'keyword',\r
-                               style: typoscriptWords[word]\r
-                       };\r
-                       return known ?\r
-                               result(known.type, known.style, word) :\r
-                               result("variable", "other", word);\r
-               }\r
-\r
-               function readRegexp() {\r
-                       nextUntilUnescaped("/");\r
-                       nextWhile(matcher(/[gi]/));\r
-                       return result("regexp", "string");\r
-               }\r
-\r
-               // Mutli-line comments are tricky. We want to return the newlines\r
-               // embedded in them as regular newline tokens, and then continue\r
-               // returning a comment token for every line of the comment. So\r
-               // some state has to be saved (inComment) to indicate whether we\r
-               // are inside a /* */ sequence.\r
-               function readMultilineComment(start) {\r
-                       this.inComment = true;\r
-                       var maybeEnd = (start == "*");\r
-                       while (true) {\r
-                               var next = source.peek();\r
-                               if (next == "\n") {\r
-                                       break;\r
-                               }\r
-                               source.next();\r
-                               if (next == "/" && maybeEnd) {\r
-                                       this.inComment = false;\r
-                                       break;\r
-                               }\r
-                               maybeEnd = (next == "*");\r
-                       }\r
-\r
-                       return result("comment", "ts-comment");\r
-               }\r
-\r
-               // Fetch the next token. Dispatches on first character in the\r
-               // stream, or first two characters when the first is a slash. The\r
-               // || things are a silly trick to keep simple cases on a single\r
-               // line.\r
-               function next() {\r
-                       var token = null;\r
-                       var ch = source.next();\r
-                       if (ch == "\n") {\r
-                               token = {\r
-                                       type: "newline",\r
-                                       style: "whitespace",\r
-                                       value: source.get()\r
-                               };\r
-                               this.inValue = false;\r
-\r
-                       } else if (!this.inValue && this.inComment) {\r
-                               token = readMultilineComment.call(this, ch);\r
-                       \r
-                       /*\r
-                       } else if (this.inValue) {\r
-                               token = nextUntilUnescaped(null) || {\r
-                                       type: "value",\r
-                                       style: "ts-value",\r
-                                       value: source.get()\r
-                               };\r
-                               this.inValue = false;\r
-                       */\r
-\r
-                       } else if (isWhiteSpace(ch)) {\r
-                               token = nextWhile(isWhiteSpace) || result("whitespace", "whitespace");\r
-\r
-                       } else if (!this.inValue && (ch == "\"" || ch == "'")) {\r
-                               token = nextUntilUnescaped(ch) || result("string", "string");\r
-\r
-                       } else if (\r
-                          ( ch == "<" || \r
-                                  ch == ">" ||\r
-                                ( ch == "=" \r
-                                  && source.peek() != "<" \r
-                                )\r
-                          )\r
-                          && source.peek() != "\n" ) { // there must be some value behind the operator!\r
-                               this.inValue = true;\r
-                               token = result(ch, "ts-operator");\r
-\r
-                       } else if (!this.inValue && ch == "[") {\r
-                               token = nextUntilUnescaped("]") || result("condition", "ts-condition");\r
-\r
-                       // with punctuation, the type of the token is the symbol itself\r
-                       } else if (!this.inValue && /[\[\]\(\),;\:\.\<\>\=]/.test(ch)) {\r
-                               token = result(ch, "ts-operator");\r
-\r
-                       } else if (!this.inValue && (ch == "{" || ch == "}")) {\r
-                               token = result(ch, "ts-operator curly-bracket");\r
-\r
-                       } else if (!this.inValue && ch == "0" && (source.peek() == "x" || source.peek() == "X")) {\r
-                               token = readHexNumber();\r
-\r
-                       } else if (!this.inValue && isDigit(ch)) {\r
-                               token = readNumber();\r
-\r
-                       } else if (!this.inValue && ch == "/") {\r
-                               next = source.peek();\r
-\r
-                               if (next == "*") {\r
-                                       token = readMultilineComment.call(this, ch);\r
-\r
-                               } else if (next == "/") {\r
-                                       token = nextUntilUnescaped(null) || result("comment", "ts-comment");\r
-\r
-                               } else if (this.regexp) {\r
-                                       token = readRegexp();\r
-\r
-                               } else {\r
-                                       token = nextWhile(isOperatorChar) || result("operator", "ts-operator");\r
-                               }\r
-\r
-                       } else if (!this.inValue && ch == "#") {\r
-                               token = nextUntilUnescaped(null) || result("comment", "ts-comment");\r
-\r
-                       } else if (!this.inValue && isOperatorChar(ch)) {\r
-                               token = nextWhile(isOperatorChar) || result("operator", "ts-operator");\r
-\r
-                       } else {\r
-                               token = readWord();\r
-                               if (this.inValue) {\r
-                                       token.style += ' ts-value';\r
-                               }\r
-                       }\r
-\r
-                       // JavaScript's syntax rules for when a slash might be the start\r
-                       // of a regexp and when it is just a division operator are kind\r
-                       // of non-obvious. This decides, based on the current token,\r
-                       // whether the next token could be a regular expression.\r
-                       if (token.style != "whitespace" && token != "comment") {\r
-                               this.regexp = token.type == "operator" || token.type == "keyword c" || token.type.match(/[\[{}\(,;:]/);\r
-                       }\r
-                       return token;\r
-               }\r
-\r
-               // Wrap it in an iterator. The state (regexp and inComment) is\r
-               // exposed because a parser will need to save it when making a\r
-               // copy of its state.\r
-               return {\r
-                       next: next,\r
-                       regexp: true,\r
-                       inComment: false,\r
-                       inValue: false\r
-               };\r
-       }\r
-} ();\r
-/* Tokenizer for TypoScript code\r
- *\r
- * based on tokenizejavascript.js by Marijn Haverbeke\r
- */\r
-\r
-// List of "reserved" word in typoscript and a css-class\r
-var typoscriptWords = {\r
-       '_CSS_DEFAULT_STYLE': 'keyword',\r
-       '_DEFAULT_PI_VARS': 'keyword',\r
-       '_GIFBUILDER': 'keyword',\r
-       '_LOCAL_LANG': 'keyword',\r
-       'CARRAY': 'keyword',\r
-       'CASE': 'keyword',\r
-       'CLEARGIF': 'keyword',\r
-       'COA': 'keyword',\r
-       'COA_INT': 'keyword',\r
-       'COBJ_ARRAY': 'keyword',\r
-       'COLUMNS': 'keyword',\r
-       'CONFIG': 'keyword',\r
-       'CONSTANTS': 'keyword',\r
-       'CONTENT': 'keyword',\r
-       'CTABLE': 'keyword',\r
-       'CType': 'keyword',\r
-       'DB': 'keyword',\r
-       'DOCUMENT_BODY': 'keyword',\r
-       'EDITPANEL': 'keyword',\r
-       'EFFECT': 'keyword',\r
-       'FE_DATA': 'keyword',\r
-       'FE_TABLE': 'keyword',\r
-       'FEData': 'keyword',\r
-       'FILE': 'keyword',\r
-       'FORM': 'keyword',\r
-       'FRAME': 'keyword',\r
-       'FRAMESET': 'keyword',\r
-       'GIFBUILDER': 'keyword',\r
-       'global': 'keyword',\r
-       'globalString': 'keyword',\r
-       'globalVar': 'keyword',\r
-       'GMENU': 'keyword',\r
-       'GMENU_FOLDOUT': 'keyword',\r
-       'GMENU_LAYERS': 'keyword',\r
-       'GP': 'keyword',\r
-       'HMENU': 'keyword',\r
-       'HRULER': 'keyword',\r
-       'HTML': 'keyword',\r
-       'IENV': 'keyword',\r
-       'IMAGE': 'keyword',\r
-       'IMG_RESOURCE': 'keyword',\r
-       'IMGMENU': 'keyword',\r
-       'IMGMENUITEM': 'keyword',\r
-       'IMGTEXT': 'keyword',\r
-       'INCLUDE_TYPOSCRIPT': 'keyword',\r
-       'includeLibs': 'keyword',\r
-       'JSMENU': 'keyword',\r
-       'JSMENUITEM': 'keyword',\r
-       'LIT': 'keyword',\r
-       'LOAD_REGISTER': 'keyword',\r
-       'META': 'keyword',\r
-       'MULTIMEDIA': 'keyword',\r
-       'OTABLE': 'keyword',\r
-       'PAGE': 'keyword',\r
-       'PAGE_TARGET': 'keyword',\r
-       'PAGE_TSCONFIG_ID': 'keyword',\r
-       'PAGE_TSCONFIG_IDLIST': 'keyword',\r
-       'PAGE_TSCONFIG_STR': 'keyword',\r
-       'PHP_SCRIPT': 'keyword',\r
-       'PHP_SCRIPT_EXT': 'keyword',\r
-       'PHP_SCRIPT_INT': 'keyword',\r
-       'RECORDS': 'keyword',\r
-       'REMOTE_ADDR': 'keyword',\r
-       'RESTORE_REGISTER': 'keyword',\r
-       'RTE': 'keyword',\r
-       'SEARCHRESULT': 'keyword',\r
-       'SHARED': 'keyword',\r
-       'TCAdefaults': 'keyword',\r
-       'TCEFORM': 'keyword',\r
-       'TCEMAIN': 'keyword',\r
-       'TEMPLATE': 'keyword',\r
-       'TEXT': 'keyword',\r
-       'TMENU': 'keyword',\r
-       'TMENU_LAYERS': 'keyword',\r
-       'TMENUITEM': 'keyword',\r
-       'TSFE': 'keyword',\r
-       'USER': 'keyword',\r
-       'USER_INT': 'keyword',\r
-       \r
-       'userFunc': 'keyword',\r
-\r
-       '_offset': 'reserved',\r
-       'absRefPrefix': 'reserved',\r
-       'accessibility': 'reserved',\r
-       'accessKey': 'reserved',\r
-       'addAttributes': 'reserved',\r
-       'addExtUrlsAndShortCuts': 'reserved',\r
-       'addItems': 'reserved',\r
-       'additionalHeaders': 'reserved',\r
-       'additionalParams': 'reserved',\r
-       'addParams': 'reserved',\r
-       'addQueryString': 'reserved',\r
-       'adjustItemsH': 'reserved',\r
-       'adjustSubItemsH': 'reserved',\r
-       'adminPanelStyles': 'reserved',\r
-       'after': 'reserved',\r
-       'afterImg': 'reserved',\r
-       'afterImgLink': 'reserved',\r
-       'afterImgTagParams': 'reserved',\r
-       'afterROImg': 'reserved',\r
-       'afterWrap': 'reserved',\r
-       'age': 'reserved',\r
-       'alertPopups': 'reserved',\r
-       'align': 'reserved',\r
-       'allow': 'reserved',\r
-       'allowCaching': 'reserved',\r
-       'allowedAttribs': 'reserved',\r
-       'allowedClasses': 'reserved',\r
-       'allowedCols': 'reserved',\r
-       'allowEdit': 'reserved',\r
-       'allowedNewTables': 'reserved',\r
-       'allowNew': 'reserved',\r
-       'allowTags': 'reserved',\r
-       'allowTVlisting': 'reserved',\r
-       'allSaveFunctions': 'reserved',\r
-       'allStdWrap': 'reserved',\r
-       'allWrap': 'reserved',\r
-       'alternateBgColors': 'reserved',\r
-       'alternativeSortingField': 'reserved',\r
-       'alternativeTempPath': 'reserved',\r
-       'altImgResource': 'reserved',\r
-       'altLabels': 'reserved',\r
-       'altTarget': 'reserved',\r
-       'altText': 'reserved',\r
-       'altUrl': 'reserved',\r
-       'altUrl_noDefaultParams': 'reserved',\r
-       'altWrap': 'reserved',\r
-       'always': 'reserved',\r
-       'alwaysActivePIDlist': 'reserved',\r
-       'alwaysLink': 'reserved',\r
-       'alwaysShowClickMenuInTopFrame': 'reserved',\r
-       'andWhere': 'reserved',\r
-       'angle': 'reserved',\r
-       'antiAlias': 'reserved',\r
-       'append': 'reserved',\r
-       'applyTotalH': 'reserved',\r
-       'applyTotalW': 'reserved',\r
-       'archive': 'reserved',\r
-       'archiveTypoLink': 'reserved',\r
-       'arrayReturnMode': 'reserved',\r
-       'arrowACT': 'reserved',\r
-       'arrowImgParams': 'reserved',\r
-       'arrowNO': 'reserved',\r
-       'ATagAfterWrap': 'reserved',\r
-       'ATagBeforeWrap': 'reserved',\r
-       'ATagParams': 'reserved',\r
-       'ATagTitle': 'reserved',\r
-       'attribute': 'reserved',\r
-       'autoInsertPID': 'reserved',\r
-       'autoLevels': 'reserved',\r
-       'autonumber': 'reserved',\r
-       'backColor': 'reserved',\r
-       'background': 'reserved',\r
-       'badMess': 'reserved',\r
-       'baseURL': 'reserved',\r
-       'before': 'reserved',\r
-       'beforeImg': 'reserved',\r
-       'beforeImgLink': 'reserved',\r
-       'beforeImgTagParams': 'reserved',\r
-       'beforeROImg': 'reserved',\r
-       'beforeWrap': 'reserved',\r
-       'begin': 'reserved',\r
-       'beLoginLinkIPList': 'reserved',\r
-       'beLoginLinkIPList_login': 'reserved',\r
-       'beLoginLinkIPList_logout': 'reserved',\r
-       'bgCol': 'reserved',\r
-       'bgImg': 'reserved',\r
-       'blankStrEqFalse': 'reserved',\r
-       'blur': 'reserved',\r
-       'bm': 'reserved',\r
-       'bodyTag': 'reserved',\r
-       'bodyTagAdd': 'reserved',\r
-       'bodyTagCObject': 'reserved',\r
-       'bodyTagMargins': 'reserved',\r
-       'bodytext': 'reserved',\r
-       'border': 'reserved',\r
-       'borderCol': 'reserved',\r
-       'bordersWithin': 'reserved',\r
-       'borderThick': 'reserved',\r
-       'bottomBackColor': 'reserved',\r
-       'bottomContent': 'reserved',\r
-       'bottomHeight': 'reserved',\r
-       'bottomImg': 'reserved',\r
-       'bottomImg_mask': 'reserved',\r
-       'br': 'reserved',\r
-       'brTag': 'reserved',\r
-       'bullet': 'reserved',\r
-       'bulletlist': 'reserved',\r
-       'bytes': 'reserved',\r
-       'cache_clearAtMidnight': 'reserved',\r
-       'cache_period': 'reserved',\r
-       'caption': 'reserved',\r
-       'caption_stdWrap': 'reserved',\r
-       'captionAlign': 'reserved',\r
-       'captionHeader': 'reserved',\r
-       'captionSplit': 'reserved',\r
-       'case': 'reserved',\r
-       'casesensitiveComp': 'reserved',\r
-       'cellpadding': 'reserved',\r
-       'cellspacing': 'reserved',\r
-       'centerImgACT': 'reserved',\r
-       'centerImgCUR': 'reserved',\r
-       'centerImgNO': 'reserved',\r
-       'centerLeftImgACT': 'reserved',\r
-       'centerLeftImgCUR': 'reserved',\r
-       'centerLeftImgNO': 'reserved',\r
-       'centerRightImgACT': 'reserved',\r
-       'centerRightImgCUR': 'reserved',\r
-       'centerRightImgNO': 'reserved',\r
-       'char': 'reserved',\r
-       'charcoal': 'reserved',\r
-       'charMapConfig': 'reserved',\r
-       'check': 'reserved',\r
-       'class': 'reserved',\r
-       'classesAnchor': 'reserved',\r
-       'classesCharacter': 'reserved',\r
-       'classesImage': 'reserved',\r
-       'classesParagraph': 'reserved',\r
-       'classicPageEditMode': 'reserved',\r
-       'clear': 'reserved',\r
-       'clearCache': 'reserved',\r
-       'clearCache_disable': 'reserved',\r
-       'clearCache_pageGrandParent': 'reserved',\r
-       'clearCache_pageSiblingChildren': 'reserved',\r
-       'clearCacheCmd': 'reserved',\r
-       'clearCacheLevels': 'reserved',\r
-       'clearCacheOfPages': 'reserved',\r
-       'clickMenuTimeOut': 'reserved',\r
-       'clickTitleMode': 'reserved',\r
-       'clipboardNumberPads': 'reserved',\r
-       'cMargins': 'reserved',\r
-       'cObjNum': 'reserved',\r
-       'collapse': 'reserved',\r
-       'color': 'reserved',\r
-       'color1': 'reserved',\r
-       'color2': 'reserved',\r
-       'color3': 'reserved',\r
-       'color4': 'reserved',\r
-       'colors': 'reserved',\r
-       'colour': 'reserved',\r
-       'colPos_list': 'reserved',\r
-       'colRelations': 'reserved',\r
-       'cols': 'reserved',\r
-       'colSpace': 'reserved',\r
-       'comment_auto': 'reserved',\r
-       'commentWrap': 'reserved',\r
-       'compensateFieldWidth': 'reserved',\r
-       'compX': 'reserved',\r
-       'compY': 'reserved',\r
-       'condensedMode': 'reserved',\r
-       'conf': 'reserved',\r
-       'constants': 'reserved',\r
-       'content_from_pid_allowOutsideDomain': 'reserved',\r
-       'contextMenu': 'reserved',\r
-       'copyLevels': 'reserved',\r
-       'count_HMENU_MENUOBJ': 'reserved',\r
-       'count_menuItems': 'reserved',\r
-       'count_MENUOBJ': 'reserved',\r
-       'create': 'reserved',\r
-       'createFoldersInEB': 'reserved',\r
-       'crop': 'reserved',\r
-       'csConv': 'reserved',\r
-       'CSS_inlineStyle': 'reserved',\r
-       'current': 'reserved',\r
-       'curUid': 'reserved',\r
-       'cWidth': 'reserved',\r
-       'data': 'reserved',\r
-       'dataWrap': 'reserved',\r
-       'date': 'reserved',\r
-       'date_stdWrap': 'reserved',\r
-       'datePrefix': 'reserved',\r
-       'debug': 'reserved',\r
-       'debugData': 'reserved',\r
-       'debugFunc': 'reserved',\r
-       'debugItemConf': 'reserved',\r
-       'debugRenumberedObject': 'reserved',\r
-       'default': 'reserved',\r
-       'defaultAlign': 'reserved',\r
-       'defaultCmd': 'reserved',\r
-       'defaultFileUploads': 'reserved',\r
-       'defaultHeaderType': 'reserved',\r
-       'defaultOutput': 'reserved',\r
-       'defaults': 'reserved',\r
-       'defaultType': 'reserved',\r
-       'delete': 'reserved',\r
-       'denyTags': 'reserved',\r
-       'depth': 'reserved',\r
-       'DESC': 'reserved',\r
-       'dimensions': 'reserved',\r
-       'directionLeft': 'reserved',\r
-       'directionUp': 'reserved',\r
-       'disableAdvanced': 'reserved',\r
-       'disableAllHeaderCode': 'reserved',\r
-       'disableAltText': 'reserved',\r
-       'disableBigButtons': 'reserved',\r
-       'disableCacheSelector': 'reserved',\r
-       'disableCharsetHeader': 'reserved',\r
-       'disableCMlayers': 'reserved',\r
-       'disabled': 'reserved',\r
-       'disableDelete': 'reserved',\r
-       'disableDocModuleInAB': 'reserved',\r
-       'disableDocSelector': 'reserved',\r
-       'disableHideAtCopy': 'reserved',\r
-       'disableIconLinkToContextmenu': 'reserved',\r
-       'disableItems': 'reserved',\r
-       'disableNewContentElementWizard': 'reserved',\r
-       'disableNoMatchingValueElement': 'reserved',\r
-       'disablePageExternalUrl': 'reserved',\r
-       'disablePrefixComment': 'reserved',\r
-       'disablePrependAtCopy': 'reserved',\r
-       'disableSearchBox': 'reserved',\r
-       'disableSingleTableView': 'reserved',\r
-       'disableTabInTextarea': 'reserved',\r
-       'displayActiveOnLoad': 'reserved',\r
-       'displayContent': 'reserved',\r
-       'displayFieldIcons': 'reserved',\r
-       'displayIcons': 'reserved',\r
-       'displayMessages': 'reserved',\r
-       'displayQueries': 'reserved',\r
-       'displayRecord': 'reserved',\r
-       'displayTimes': 'reserved',\r
-       'distributeX': 'reserved',\r
-       'distributeY': 'reserved',\r
-       'DIV': 'reserved',\r
-       'doctype': 'reserved',\r
-       'doctypeSwitch': 'reserved',\r
-       'doktype': 'reserved',\r
-       'doNotLinkIt': 'reserved',\r
-       'doNotShowLink': 'reserved',\r
-       'doNotStripHTML': 'reserved',\r
-       'dontCheckPid': 'reserved',\r
-       'dontFollowMouse': 'reserved',\r
-       'dontHideOnMouseUp': 'reserved',\r
-       'dontLinkIfSubmenu': 'reserved',\r
-       'dontShowPalettesOnFocusInAB': 'reserved',\r
-       'dontWrapInTable': 'reserved',\r
-       'doubleBrTag': 'reserved',\r
-       'doublePostCheck': 'reserved',\r
-       'dWorkArea': 'reserved',\r
-       'edge': 'reserved',\r
-       'edit_docModuleUplaod': 'reserved',\r
-       'edit_docModuleUpload': 'reserved',\r
-       'edit_RTE': 'reserved',\r
-       'edit_showFieldHelp': 'reserved',\r
-       'edit_wideDocument': 'reserved',\r
-       'editFieldsAtATime': 'reserved',\r
-       'editFormsOnPage': 'reserved',\r
-       'editIcons': 'reserved',\r
-       'editNoPopup': 'reserved',\r
-       'editPanel': 'reserved',\r
-       'elements': 'reserved',\r
-       'emailMeAtLogin': 'reserved',\r
-       'emailMess': 'reserved',\r
-       'emboss': 'reserved',\r
-       'enable': 'reserved',\r
-       'encapsLines': 'reserved',\r
-       'encapsLinesStdWrap': 'reserved',\r
-       'encapsTagList': 'reserved',\r
-       'entryLevel': 'reserved',\r
-       'equalH': 'reserved',\r
-       'everybody': 'reserved',\r
-       'excludeDoktypes': 'reserved',\r
-       'excludeUidList': 'reserved',\r
-       'expAll': 'reserved',\r
-       'expand': 'reserved',\r
-       'explode': 'reserved',\r
-       'ext': 'reserved',\r
-       'externalBlocks': 'reserved',\r
-       'extTarget': 'reserved',\r
-       'face': 'reserved',\r
-       'fe_adminLib': 'reserved',\r
-       'field': 'reserved',\r
-       'fieldOrder': 'reserved',\r
-       'fieldRequired': 'reserved',\r
-       'fields': 'reserved',\r
-       'fieldWrap': 'reserved',\r
-       'file': 'reserved',\r
-       'file1': 'reserved',\r
-       'file2': 'reserved',\r
-       'file3': 'reserved',\r
-       'file4': 'reserved',\r
-       'file5': 'reserved',\r
-       'filelink': 'reserved',\r
-       'filelist': 'reserved',\r
-       'firstLabel': 'reserved',\r
-       'firstLabelGeneral': 'reserved',\r
-       'fixAttrib': 'reserved',\r
-       'flip': 'reserved',\r
-       'flop': 'reserved',\r
-       'foldSpeed': 'reserved',\r
-       'foldTimer': 'reserved',\r
-       'fontColor': 'reserved',\r
-       'fontFile': 'reserved',\r
-       'fontOffset': 'reserved',\r
-       'fontSize': 'reserved',\r
-       'fontSizeMultiplicator': 'reserved',\r
-       'fontTag': 'reserved',\r
-       'forceDisplayFieldIcons': 'reserved',\r
-       'forceDisplayIcons': 'reserved',\r
-       'forceNoPopup': 'reserved',\r
-       'forceTemplateParsing': 'reserved',\r
-       'forceTypeValue': 'reserved',\r
-       'format': 'reserved',\r
-       'frame': 'reserved',\r
-       'frameReloadIfNotInFrameset': 'reserved',\r
-       'frameSet': 'reserved',\r
-       'freezeMouseover': 'reserved',\r
-       'ftu': 'reserved',\r
-       'function': 'reserved',\r
-       'gamma': 'reserved',\r
-       'gapBgCol': 'reserved',\r
-       'gapLineCol': 'reserved',\r
-       'gapLineThickness': 'reserved',\r
-       'gapWidth': 'reserved',\r
-       'get': 'reserved',\r
-       'getBorder': 'reserved',\r
-       'getLeft': 'reserved',\r
-       'getRight': 'reserved',\r
-       'globalNesting': 'reserved',\r
-       'goodMess': 'reserved',\r
-       'gray': 'reserved',\r
-       'group': 'reserved',\r
-       'groupBy': 'reserved',\r
-       'groupid': 'reserved',\r
-       'header': 'reserved',\r
-       'header_layout': 'reserved',\r
-       'headerComment': 'reserved',\r
-       'headerData': 'reserved',\r
-       'headerSpace': 'reserved',\r
-       'headTag': 'reserved',\r
-       'height': 'reserved',\r
-       'helpText': 'reserved',\r
-       'hidden': 'reserved',\r
-       'hiddenFields': 'reserved',\r
-       'hide': 'reserved',\r
-       'hideButCreateMap': 'reserved',\r
-       'hideMenuTimer': 'reserved',\r
-       'hideMenuWhenNotOver': 'reserved',\r
-       'hidePStyleItems': 'reserved',\r
-       'hideRecords': 'reserved',\r
-       'hideSubmoduleIcons': 'reserved',\r
-       'highColor': 'reserved',\r
-       'history': 'reserved',\r
-       'hover': 'reserved',\r
-       'hoverStyle': 'reserved',\r
-       'HTMLparser': 'reserved',\r
-       'HTMLparser_tags': 'reserved',\r
-       'htmlSpecialChars': 'reserved',\r
-       'htmlTag_dir': 'reserved',\r
-       'htmlTag_langKey': 'reserved',\r
-       'htmlTag_setParams': 'reserved',\r
-       'http': 'reserved',\r
-       'icon': 'reserved',\r
-       'icon_image_ext_list': 'reserved',\r
-       'icon_link': 'reserved',\r
-       'iconCObject': 'reserved',\r
-       'ifEmpty': 'reserved',\r
-       'image': 'reserved',\r
-       'image_compression': 'reserved',\r
-       'image_effects': 'reserved',\r
-       'image_frames': 'reserved',\r
-       'imageLinkWrap': 'reserved',\r
-       'imagePath': 'reserved',\r
-       'images': 'reserved',\r
-       'imageWrapIfAny': 'reserved',\r
-       'imgList': 'reserved',\r
-       'imgMap': 'reserved',\r
-       'imgMapExtras': 'reserved',\r
-       'imgMax': 'reserved',\r
-       'imgNameNotRandom': 'reserved',\r
-       'imgNamePrefix': 'reserved',\r
-       'imgObjNum': 'reserved',\r
-       'imgParams': 'reserved',\r
-       'imgPath': 'reserved',\r
-       'imgStart': 'reserved',\r
-       'import': 'reserved',\r
-       'inc': 'reserved',\r
-       'includeCSS': 'reserved',\r
-       'includeLibrary': 'reserved',\r
-       'includeNotInMenu': 'reserved',\r
-       'incT3Lib_htmlmail': 'reserved',\r
-       'index': 'reserved',\r
-       'index_descrLgd': 'reserved',\r
-       'index_enable': 'reserved',\r
-       'index_externals': 'reserved',\r
-       'inlineStyle2TempFile': 'reserved',\r
-       'innerStdWrap': 'reserved',\r
-       'innerStdWrap_all': 'reserved',\r
-       'innerWrap': 'reserved',\r
-       'innerWrap2': 'reserved',\r
-  &