[BUGFIX] RTE in frontend with IE9: Use IE8 standards mode (TYPO3 4.5)
[Packages/TYPO3.CMS.git] / typo3 / sysext / rtehtmlarea / pi2 / class.tx_rtehtmlarea_pi2.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2005-2012 Stanislas Rolland <typo3(arobas)sjbr.ca>
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27 /**
28 * Front end RTE based on htmlArea
29 *
30 * @author Stanislas Rolland <typo3(arobas)sjbr.ca>
31 *
32 * $Id$ *
33 */
34 class tx_rtehtmlarea_pi2 extends tx_rtehtmlarea_base {
35
36 // External:
37 public $RTEWrapStyle = ''; // Alternative style for RTE wrapper <div> tag.
38 public $RTEdivStyle = ''; // Alternative style for RTE <div> tag.
39
40 // For the editor
41 var $elementId;
42 var $elementParts;
43 var $tscPID;
44 var $typeVal;
45 var $thePid;
46 var $RTEsetup = array();
47 var $thisConfig = array();
48 var $confValues;
49 public $language;
50 public $OutputCharset;
51 var $specConf;
52 var $LOCAL_LANG;
53 /**
54 * @var t3lib_PageRenderer
55 */
56 protected $pageRenderer;
57
58 /**
59 * Draws the RTE as an iframe
60 *
61 * @param object Reference to parent object, which is an instance of the TCEforms.
62 * @param string The table name
63 * @param string The field name
64 * @param array The current row from which field is being rendered
65 * @param array Array of standard content for rendering form fields from TCEforms. See TCEforms for details on this. Includes for instance the value and the form field name, java script actions and more.
66 * @param array "special" configuration - what is found at position 4 in the types configuration of a field from record, parsed into an array.
67 * @param array Configuration for RTEs; A mix between TSconfig and otherwise. Contains configuration for display, which buttons are enabled, additional transformation information etc.
68 * @param string Record "type" field value.
69 * @param string Relative path for images/links in RTE; this is used when the RTE edits content from static files where the path of such media has to be transformed forth and back!
70 * @param integer PID value of record (true parent page id)
71 * @return string HTML code for RTE!
72 */
73 function drawRTE($parentObject,$table,$field,$row,$PA,$specConf,$thisConfig,$RTEtypeVal,$RTErelPath,$thePidValue) {
74 global $TSFE, $TYPO3_CONF_VARS, $TYPO3_DB;
75
76 $this->TCEform = $parentObject;
77 $this->client = $this->clientInfo();
78 $this->typoVersion = t3lib_div::int_from_ver(TYPO3_version);
79
80 /* =======================================
81 * INIT THE EDITOR-SETTINGS
82 * =======================================
83 */
84 // Get the path to this extension:
85 $this->extHttpPath = t3lib_extMgm::siteRelPath($this->ID);
86 // Get the site URL
87 $this->siteURL = $GLOBALS['TSFE']->absRefPrefix ? $GLOBALS['TSFE']->absRefPrefix : '';
88 // Get the host URL
89 $this->hostURL = '';
90 // Element ID + pid
91 $this->elementId = $PA['itemFormElName'];
92 $this->elementParts[0] = $table;
93 $this->elementParts[1] = $row['uid'];
94 $this->tscPID = $thePidValue;
95 $this->thePid = $thePidValue;
96
97 // Record "type" field value:
98 $this->typeVal = $RTEtypeVal; // TCA "type" value for record
99
100 // RTE configuration
101 $pageTSConfig = $TSFE->getPagesTSconfig();
102 if (is_array($pageTSConfig) && is_array($pageTSConfig['RTE.'])) {
103 $this->RTEsetup = $pageTSConfig['RTE.'];
104 }
105
106 if (is_array($thisConfig) && !empty($thisConfig)) {
107 $this->thisConfig = $thisConfig;
108 } else if (is_array($this->RTEsetup['default.']) && is_array($this->RTEsetup['default.']['FE.'])) {
109 $this->thisConfig = $this->RTEsetup['default.']['FE.'];
110 }
111
112 // Special configuration (line) and default extras:
113 $this->specConf = $specConf;
114
115 if ($this->thisConfig['forceHTTPS']) {
116 $this->extHttpPath = preg_replace('/^(http|https)/', 'https', $this->extHttpPath);
117 $this->siteURL = preg_replace('/^(http|https)/', 'https', $this->siteURL);
118 $this->hostURL = preg_replace('/^(http|https)/', 'https', $this->hostURL);
119 }
120 // Register RTE windows:
121 $this->TCEform->RTEwindows[] = $PA['itemFormElName'];
122 $textAreaId = preg_replace('/[^a-zA-Z0-9_:.-]/', '_', $PA['itemFormElName']);
123 $textAreaId = htmlspecialchars(preg_replace('/^[^a-zA-Z]/', 'x', $textAreaId)) . '_' . strval($this->TCEform->RTEcounter);
124 /* =======================================
125 * LANGUAGES & CHARACTER SETS
126 * =======================================
127 */
128 // Language
129 $TSFE->initLLvars();
130 $this->language = $TSFE->lang;
131 $this->LOCAL_LANG = t3lib_div::readLLfile('EXT:' . $this->ID . '/locallang.xml', $this->language);
132 if ($this->language == 'default' || !$this->language) {
133 $this->language = 'en';
134 }
135 $this->contentLanguageUid = ($row['sys_language_uid'] > 0) ? $row['sys_language_uid'] : 0;
136 if (t3lib_extMgm::isLoaded('static_info_tables')) {
137 if ($this->contentLanguageUid) {
138 $tableA = 'sys_language';
139 $tableB = 'static_languages';
140 $languagesUidsList = $this->contentLanguageUid;
141 $selectFields = $tableA . '.uid,' . $tableB . '.lg_iso_2,' . $tableB . '.lg_country_iso_2,' . $tableB . '.lg_typo3';
142 $tableAB = $tableA . ' LEFT JOIN ' . $tableB . ' ON ' . $tableA . '.static_lang_isocode=' . $tableB . '.uid';
143 $whereClause = $tableA . '.uid IN (' . $languagesUidsList . ') ';
144 $whereClause .= t3lib_BEfunc::BEenableFields($tableA);
145 $whereClause .= t3lib_BEfunc::deleteClause($tableA);
146 $res = $TYPO3_DB->exec_SELECTquery($selectFields, $tableAB, $whereClause);
147 while($languageRow = $TYPO3_DB->sql_fetch_assoc($res)) {
148 $this->contentISOLanguage = strtolower(trim($languageRow['lg_iso_2']).(trim($languageRow['lg_country_iso_2'])?'_'.trim($languageRow['lg_country_iso_2']):''));
149 $this->contentTypo3Language = strtolower(trim($languageRow['lg_typo3']));
150 }
151 } else {
152 $this->contentISOLanguage = $GLOBALS['TSFE']->sys_language_isocode ? $GLOBALS['TSFE']->sys_language_isocode : 'en';
153 $selectFields = 'lg_iso_2, lg_typo3';
154 $tableAB = 'static_languages';
155 $whereClause = 'lg_iso_2 = ' . $TYPO3_DB->fullQuoteStr(strtoupper($this->contentISOLanguage), $tableAB);
156 $res = $TYPO3_DB->exec_SELECTquery($selectFields, $tableAB, $whereClause);
157 while($languageRow = $TYPO3_DB->sql_fetch_assoc($res)) {
158 $this->contentTypo3Language = strtolower(trim($languageRow['lg_typo3']));
159 }
160 }
161 }
162 $this->contentISOLanguage = $this->contentISOLanguage ? $this->contentISOLanguage : ($GLOBALS['TSFE']->sys_language_isocode ? $GLOBALS['TSFE']->sys_language_isocode : 'en');
163 $this->contentTypo3Language = $this->contentTypo3Language ? $this->contentTypo3Language : $GLOBALS['TSFE']->lang;
164 if ($this->contentTypo3Language == 'default') {
165 $this->contentTypo3Language = 'en';
166 }
167
168 // Character set
169 $this->charset = $TSFE->renderCharset;
170 $this->OutputCharset = $TSFE->metaCharset ? $TSFE->metaCharset : $TSFE->renderCharset;
171
172 // Set the charset of the content
173 $this->contentCharset = $TSFE->csConvObj->charSetArray[$this->contentTypo3Language];
174 $this->contentCharset = $this->contentCharset ? $this->contentCharset : 'iso-8859-1';
175 $this->contentCharset = trim($TSFE->config['config']['metaCharset']) ? trim($TSFE->config['config']['metaCharset']) : $this->contentCharset;
176
177 /* =======================================
178 * TOOLBAR CONFIGURATION
179 * =======================================
180 */
181 $this->initializeToolbarConfiguration();
182
183 /* =======================================
184 * SET STYLES
185 * =======================================
186 */
187
188 $width = 460+($this->TCEform->docLarge ? 150 : 0);
189 if (isset($this->thisConfig['RTEWidthOverride'])) {
190 if (strstr($this->thisConfig['RTEWidthOverride'], '%')) {
191 if ($this->client['browser'] != 'msie') {
192 $width = (intval($this->thisConfig['RTEWidthOverride']) > 0) ? $this->thisConfig['RTEWidthOverride'] : '100%';
193 }
194 } else {
195 $width = (intval($this->thisConfig['RTEWidthOverride']) > 0) ? intval($this->thisConfig['RTEWidthOverride']) : $width;
196 }
197 }
198 $RTEWidth = strstr($width, '%') ? $width : $width . 'px';
199 $editorWrapWidth = strstr($width, '%') ? $width : ($width+2) . 'px';
200 $height = 380;
201 $RTEHeightOverride = intval($this->thisConfig['RTEHeightOverride']);
202 $height = ($RTEHeightOverride > 0) ? $RTEHeightOverride : $height;
203 $RTEHeight = $height . 'px';
204 $editorWrapHeight = ($height+2) . 'px';
205 $this->RTEWrapStyle = $this->RTEWrapStyle ? $this->RTEWrapStyle : ($this->RTEdivStyle ? $this->RTEdivStyle : ('height:' . $editorWrapHeight . '; width:'. $editorWrapWidth . ';'));
206 $this->RTEdivStyle = $this->RTEdivStyle ? $this->RTEdivStyle : 'position:relative; left:0px; top:0px; height:' . $RTEHeight . '; width:'.$RTEWidth.'; border: 1px solid black;';
207
208 /* =======================================
209 * LOAD JS, CSS and more
210 * =======================================
211 */
212 $pageRenderer = $this->getPageRenderer();
213 // Add metatag for IE9 to use IE8 standards mode
214 // ExtJS 3.3 does not support IE9 standards mode
215 $pageRenderer->addMetaTag('<meta http-equiv="X-UA-Compatible" content="IE=8" />');
216 // Preloading the pageStyle and including RTE skin stylesheets
217 $this->addPageStyle();
218 $this->addSkin();
219 // Re-initialize the scripts array so that only the cumulative set of plugins of the last RTE on the page is used
220 $this->cumulativeScripts[$this->TCEform->RTEcounter] = array();
221 $this->includeScriptFiles($this->TCEform->RTEcounter);
222 $this->buildJSMainLangFile($this->TCEform->RTEcounter);
223 // Register RTE in JS:
224 $this->TCEform->additionalJS_post[] = $this->wrapCDATA($this->registerRTEinJS($this->TCEform->RTEcounter, '', '', '',$textAreaId));
225 // Set the save option for the RTE:
226 $this->TCEform->additionalJS_submit[] = $this->setSaveRTE($this->TCEform->RTEcounter, $this->TCEform->formName, $textAreaId);
227 // Loading ExtJs JavaScript files and inline code, if not configured in TS setup
228 if (!$GLOBALS['TSFE']->isINTincScript() || !is_array($GLOBALS['TSFE']->pSetup['javascriptLibs.']['ExtJs.'])) {
229 $pageRenderer->loadExtJs();
230 $pageRenderer->enableExtJSQuickTips();
231 if (!$GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->ID]['enableCompressedScripts']) {
232 $pageRenderer->enableExtJsDebug();
233 }
234 }
235 $pageRenderer->addCssFile($this->siteURL . 't3lib/js/extjs/ux/resize.css');
236 $pageRenderer->addJsFile($this->siteURL . 't3lib/js/extjs/ux/ext.resizable.js');
237 $pageRenderer->addJsFile($this->siteURL . '/t3lib/js/extjs/notifications.js');
238 if ($this->TCEform->RTEcounter == 1) {
239 $this->TCEform->additionalJS_pre['rtehtmlarea-loadJScode'] = $this->wrapCDATA($this->loadJScode($this->TCEform->RTEcounter));
240 }
241 $this->TCEform->additionalJS_initial = $this->loadJSfiles($this->TCEform->RTEcounter);
242 if ($GLOBALS['TSFE']->isINTincScript()) {
243 $GLOBALS['TSFE']->additionalHeaderData['rtehtmlarea'] = $pageRenderer->render();
244 }
245 /* =======================================
246 * DRAW THE EDITOR
247 * =======================================
248 */
249 // Transform value:
250 $value = $this->transformContent('rte',$PA['itemFormElValue'],$table,$field,$row,$specConf,$thisConfig,$RTErelPath,$thePidValue);
251
252 // Further content transformation by registered plugins
253 foreach ($this->registeredPlugins as $pluginId => $plugin) {
254 if ($this->isPluginEnabled($pluginId) && method_exists($plugin, "transformContent")) {
255 $value = $plugin->transformContent($value);
256 }
257 }
258 // draw the textarea
259 $item = $this->triggerField($PA['itemFormElName']).'
260 <div id="pleasewait' . $textAreaId . '" class="pleasewait" style="display: block;" >' . $TSFE->csConvObj->conv($TSFE->getLLL('Please wait',$this->LOCAL_LANG), $this->charset, $TSFE->renderCharset) . '</div>
261 <div id="editorWrap' . $textAreaId . '" class="editorWrap" style="visibility: hidden; '. htmlspecialchars($this->RTEWrapStyle). '">
262 <textarea id="RTEarea' . $textAreaId . '" name="'.htmlspecialchars($PA['itemFormElName']).'" rows="0" cols="0" style="'.htmlspecialchars($this->RTEdivStyle).'">'.t3lib_div::formatForTextarea($value).'</textarea>
263 </div>' . ($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['enableDebugMode'] ? '<div id="HTMLAreaLog"></div>' : '') . '
264 ';
265 return $item;
266 }
267 /**
268 * Add style sheet file to document header
269 *
270 * @param string $key: some key identifying the style sheet
271 * @param string $href: uri to the style sheet file
272 * @param string $title: value for the title attribute of the link element
273 * @return string $relation: value for the rel attribute of the link element
274 * @return void
275 */
276 protected function addStyleSheet($key, $href, $title='', $relation='stylesheet') {
277 $this->pageRenderer->addCssFile($href, $relation, 'screen', $title);
278 }
279 /**
280 * Return the JS-Code for copy the HTML-Code from the editor in the hidden input field.
281 * This is for submit function from the form.
282 *
283 * @param integer $RTEcounter: The index number of the RTE editing area.
284 * @param string $form: the name of the form
285 * @param string $textareaId: the id of the textarea
286 *
287 * @return string the JS-Code
288 */
289 function setSaveRTE($RTEcounter, $form, $textareaId) {
290 return '
291 if (RTEarea[\'' . $textareaId . '\'] && !RTEarea[\'' . $textareaId . '\'].deleted) {
292 var field = document.getElementById(\'RTEarea' . $textareaId . '\');
293 if (field && field.nodeName.toLowerCase() == \'textarea\') {
294 field.value = RTEarea[\'' . $textareaId . '\'][\'editor\'].getHTML();
295 }
296 } else {
297 OK = 0;
298 }';
299 }
300 /**
301 * Gets instance of PageRenderer
302 *
303 * @return t3lib_PageRenderer
304 */
305 public function getPageRenderer() {
306 if (!isset($this->pageRenderer)) {
307 if ($GLOBALS['TSFE']->isINTincScript()) {
308 // We use an instance of t3lib_PageRenderer to render additional header data
309 // because this script is invoked after header has been rendered by $GLOBALS['TSFE']->getPageRenderer()
310 $this->pageRenderer = t3lib_div::makeInstance('t3lib_PageRenderer');
311 $this->pageRenderer->setTemplateFile($this->extHttpPath . 'templates/rtehtmlarea_pageheader_frontend.html');
312 } else {
313 $this->pageRenderer = $GLOBALS['TSFE']->getPageRenderer();
314 }
315 $this->pageRenderer->setBackPath(TYPO3_mainDir);
316 }
317 return $this->pageRenderer;
318 }
319 /**
320 * Wrap input string in CDATA enclosure
321 *
322 * @param string $string: input to be wrapped
323 *
324 * @return string wrapped string
325 */
326 public function wrapCDATA ($string) {
327 return implode(LF,
328 array(
329 '',
330 '/*<![CDATA[*/',
331 $string,
332 '/*]]>*/'
333 )
334 );
335 }
336 }
337 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/rtehtmlarea/pi2/class.tx_rtehtmlarea_pi2.php'])) {
338 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/rtehtmlarea/pi2/class.tx_rtehtmlarea_pi2.php']);
339 }
340 ?>