TYPO3 API  SVNRelease
class.t3lib_pagerenderer.php
Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003  *  Copyright notice
00004  *
00005  *  (c) 2009-2011 Steffen Kamper (info@sk-typo3.de)
00006  *  All rights reserved
00007  *
00008  *  This script is part of the TYPO3 project. The TYPO3 project is
00009  *  free software; you can redistribute it and/or modify
00010  *  it under the terms of the GNU General Public License as published by
00011  *  the Free Software Foundation; either version 2 of the License, or
00012  *  (at your option) any later version.
00013  *
00014  *  The GNU General Public License can be found at
00015  *  http://www.gnu.org/copyleft/gpl.html.
00016  *  A copy is found in the textfile GPL.txt and important notices to the license
00017  *  from the author is found in LICENSE.txt distributed with these scripts.
00018  *
00019  *
00020  *  This script is distributed in the hope that it will be useful,
00021  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00022  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023  *  GNU General Public License for more details.
00024  *
00025  *  This copyright notice MUST APPEAR in all copies of the script!
00026  ***************************************************************/
00027 
00028 /**
00029  * TYPO3 pageRender class (new in TYPO3 4.3.0)
00030  * This class render the HTML of a webpage, usable for BE and FE
00031  *
00032  * @author  Steffen Kamper <info@sk-typo3.de>
00033  * @package TYPO3
00034  * @subpackage t3lib
00035  * $Id: class.t3lib_pagerenderer.php 10520 2011-02-21 19:09:46Z steffenk $
00036  */
00037 class t3lib_PageRenderer implements t3lib_Singleton {
00038 
00039     protected $compressJavascript = FALSE;
00040     protected $compressCss = FALSE;
00041     protected $removeLineBreaksFromTemplate = FALSE;
00042 
00043     protected $concatenateFiles = FALSE;
00044 
00045     protected $moveJsFromHeaderToFooter = FALSE;
00046 
00047     /* @var t3lib_cs Instance of t3lib_cs */
00048     protected $csConvObj;
00049     protected $lang;
00050 
00051     /* @var t3lib_Compressor Instance of t3lib_Compressor */
00052     protected $compressor;
00053 
00054         // static array containing associative array for the included files
00055     protected static $jsFiles = array();
00056     protected static $jsFooterFiles = array();
00057     protected static $jsLibs = array();
00058     protected static $jsFooterLibs = array();
00059     protected static $cssFiles = array();
00060 
00061     protected $title;
00062     protected $charSet;
00063     protected $favIcon;
00064     protected $baseUrl;
00065 
00066     protected $renderXhtml = TRUE;
00067 
00068         // static header blocks
00069     protected $xmlPrologAndDocType = '';
00070     protected $metaTags = array();
00071     protected $inlineComments = array();
00072     protected $headerData = array();
00073     protected $footerData = array();
00074     protected $titleTag = '<title>|</title>';
00075     protected $metaCharsetTag = '<meta http-equiv="Content-Type" content="text/html; charset=|" />';
00076     protected $htmlTag = '<html>';
00077     protected $headTag = '<head>';
00078     protected $baseUrlTag = '<base href="|" />';
00079     protected $iconMimeType = '';
00080     protected $shortcutTag = '<link rel="shortcut icon" href="%1$s"%2$s />
00081 <link rel="icon" href="%1$s"%2$s />';
00082 
00083         // static inline code blocks
00084     protected $jsInline = array();
00085     protected $jsFooterInline = array();
00086     protected $extOnReadyCode = array();
00087     protected $cssInline = array();
00088 
00089     protected $bodyContent;
00090 
00091     protected $templateFile;
00092 
00093     protected $jsLibraryNames = array('prototype', 'scriptaculous', 'extjs');
00094 
00095     const PART_COMPLETE = 0;
00096     const PART_HEADER = 1;
00097     const PART_FOOTER = 2;
00098 
00099         // paths to contibuted libraries
00100     protected $prototypePath = 'contrib/prototype/';
00101     protected $scriptaculousPath = 'contrib/scriptaculous/';
00102     protected $extCorePath = 'contrib/extjs/';
00103     protected $extJsPath = 'contrib/extjs/';
00104     protected $svgPath = 'contrib/websvg/';
00105 
00106 
00107         // internal flags for JS-libraries
00108     protected $addPrototype = FALSE;
00109     protected $addScriptaculous = FALSE;
00110     protected $addScriptaculousModules = array('builder' => FALSE, 'effects' => FALSE, 'dragdrop' => FALSE, 'controls' => FALSE, 'slider' => FALSE);
00111     protected $addExtJS = FALSE;
00112     protected $addExtCore = FALSE;
00113     protected $extJSadapter = 'ext/ext-base.js';
00114     protected $extDirectCodeAdded = FALSE;
00115 
00116     protected $enableExtJsDebug = FALSE;
00117     protected $enableExtCoreDebug = FALSE;
00118 
00119         // available adapters for extJs
00120     const EXTJS_ADAPTER_JQUERY = 'jquery';
00121     const EXTJS_ADAPTER_PROTOTYPE = 'prototype';
00122     const EXTJS_ADAPTER_YUI = 'yui';
00123 
00124     protected $extJStheme = TRUE;
00125     protected $extJScss = TRUE;
00126 
00127     protected $enableExtJSQuickTips = FALSE;
00128 
00129     protected $inlineLanguageLabels = array();
00130     protected $inlineLanguageLabelFiles = array();
00131     protected $inlineSettings = array();
00132 
00133     protected $inlineJavascriptWrap = array();
00134 
00135         // saves error messages generated during compression
00136     protected $compressError = '';
00137 
00138         // SVG library
00139     protected $addSvg = FALSE;
00140     protected $enableSvgDebug = FALSE;
00141 
00142         // used by BE modules
00143     public $backPath;
00144 
00145     /**
00146      * Constructor
00147      *
00148      * @param string $templateFile  declare the used template file. Omit this parameter will use default template
00149      * @param string $backPath  relative path to typo3-folder. It varies for BE modules, in FE it will be typo3/
00150      * @return void
00151      */
00152     public function __construct($templateFile = '', $backPath = NULL) {
00153 
00154         $this->reset();
00155         $this->csConvObj = t3lib_div::makeInstance('t3lib_cs');
00156 
00157         if (strlen($templateFile)) {
00158             $this->templateFile = $templateFile;
00159         }
00160         $this->backPath = isset($backPath) ? $backPath : $GLOBALS['BACK_PATH'];
00161 
00162         $this->inlineJavascriptWrap = array(
00163             '<script type="text/javascript">' . LF . '/*<![CDATA[*/' . LF . '<!-- ' . LF,
00164             '// -->' . LF . '/*]]>*/' . LF . '</script>' . LF
00165         );
00166         $this->inlineCssWrap = array(
00167             '<style type="text/css">' . LF . '/*<![CDATA[*/' . LF . '<!-- ' . LF,
00168             '-->' . LF . '/*]]>*/' . LF . '</style>' . LF
00169         );
00170 
00171     }
00172 
00173     /**
00174      * reset all vars to initial values
00175      *
00176      * @return void
00177      */
00178     protected function reset() {
00179         $this->templateFile = TYPO3_mainDir . 'templates/template_page_backend.html';
00180         $this->jsFiles = array();
00181         $this->jsFooterFiles = array();
00182         $this->jsInline = array();
00183         $this->jsFooterInline = array();
00184         $this->jsLibs = array();
00185         $this->cssFiles = array();
00186         $this->cssInline = array();
00187         $this->metaTags = array();
00188         $this->inlineComments = array();
00189         $this->headerData = array();
00190         $this->footerData = array();
00191         $this->extOnReadyCode = array();
00192     }
00193 
00194     /*****************************************************/
00195     /*                                                   */
00196     /*  Public Setters                                   */
00197     /*                                                   */
00198     /*                                                   */
00199     /*****************************************************/
00200 
00201     /**
00202      * Sets the title
00203      *
00204      * @param string $title title of webpage
00205      * @return void
00206      */
00207     public function setTitle($title) {
00208         $this->title = $title;
00209     }
00210 
00211 
00212     /**
00213      * Enables/disables rendering of XHTML code
00214      *
00215      * @param boolean $enable   Enable XHTML
00216      * @return void
00217      */
00218     public function setRenderXhtml($enable) {
00219         $this->renderXhtml = $enable;
00220     }
00221 
00222     /**
00223      * Sets xml prolog and docType
00224      *
00225      * @param string $xmlPrologAndDocType   complete tags for xml prolog and docType
00226      * @return void
00227      */
00228     public function setXmlPrologAndDocType($xmlPrologAndDocType) {
00229         $this->xmlPrologAndDocType = $xmlPrologAndDocType;
00230     }
00231 
00232     /**
00233      * Sets meta charset
00234      *
00235      * @param string $charSet   used charset
00236      * @return void
00237      */
00238     public function setCharSet($charSet) {
00239         $this->charSet = $charSet;
00240     }
00241 
00242     /**
00243      * Sets language
00244      *
00245      * @param string $lang  used language
00246      * @return void
00247      */
00248     public function setLanguage($lang) {
00249         $this->lang = $lang;
00250     }
00251 
00252     /**
00253      * Sets html tag
00254      *
00255      * @param string $htmlTag   html tag
00256      * @return void
00257      */
00258     public function setHtmlTag($htmlTag) {
00259         $this->htmlTag = $htmlTag;
00260     }
00261 
00262     /**
00263      * Sets head tag
00264      *
00265      * @param string $tag   head tag
00266      * @return void
00267      */
00268     public function setHeadTag($headTag) {
00269         $this->headTag = $headTag;
00270     }
00271 
00272     /**
00273      * Sets favicon
00274      *
00275      * @param string $favIcon
00276      * @return void
00277      */
00278     public function setFavIcon($favIcon) {
00279         $this->favIcon = $favIcon;
00280     }
00281 
00282     /**
00283      * Sets icon mime type
00284      *
00285      * @param string $iconMimeType
00286      * @return void
00287      */
00288     public function setIconMimeType($iconMimeType) {
00289         $this->iconMimeType = $iconMimeType;
00290     }
00291 
00292     /**
00293      * Sets base url
00294      *
00295      * @param string $url
00296      * @return void
00297      */
00298     public function setBaseUrl($baseUrl) {
00299         $this->baseUrl = $baseUrl;
00300     }
00301 
00302     /**
00303      * Sets template file
00304      *
00305      * @param string $file
00306      * @return void
00307      */
00308     public function setTemplateFile($file) {
00309         $this->templateFile = $file;
00310     }
00311 
00312     /**
00313      * Sets back path
00314      *
00315      * @param string $backPath
00316      * @return void
00317      */
00318     public function setBackPath($backPath) {
00319         $this->backPath = $backPath;
00320     }
00321 
00322     /**
00323      * Sets Content for Body
00324      *
00325      * @param string $content
00326      * @return void
00327      */
00328     public function setBodyContent($content) {
00329         $this->bodyContent = $content;
00330     }
00331 
00332     /**
00333      * Sets Path for prototype library (relative to typo3 directory)
00334      *
00335      * @param string path
00336      * @return void
00337      */
00338     public function setPrototypePath($path) {
00339         $this->prototypePath = $path;
00340     }
00341 
00342     /**
00343      * Sets Path for scriptaculous library (relative to typo3 directory)
00344      *
00345      * @param string $path
00346      * @return void
00347      */
00348     public function setScriptaculousPath($path) {
00349         $this->scriptaculousPath = $path;
00350     }
00351 
00352     /**
00353      * Sets Path for Ext Core library (relative to typo3 directory)
00354      *
00355      * @param string $path
00356      * @return void
00357      */
00358     public function setExtCorePath($path) {
00359         $this->extCorePath = $path;
00360     }
00361 
00362     /**
00363      * Sets Path for ExtJs library (relative to typo3 directory)
00364      *
00365      * @param string $path
00366      * @return void
00367      */
00368     public function setExtJsPath($path) {
00369         $this->extJsPath = $path;
00370     }
00371 
00372     /**
00373      * Sets Path for SVG library (websvg)
00374      *
00375      * @param string $path
00376      * @return void
00377      */
00378     public function setSvgPath($path) {
00379         $this->svgPath = $path;
00380     }
00381 
00382     /*****************************************************/
00383     /*                                                   */
00384     /*  Public Enablers / Disablers                      */
00385     /*                                                   */
00386     /*                                                   */
00387     /*****************************************************/
00388 
00389     /**
00390      * Enables MoveJsFromHeaderToFooter
00391      *
00392      * @param void
00393      * @return void
00394      */
00395     public function enableMoveJsFromHeaderToFooter() {
00396         $this->moveJsFromHeaderToFooter = TRUE;
00397     }
00398 
00399     /**
00400      * Disables MoveJsFromHeaderToFooter
00401      *
00402      * @param void
00403      * @return void
00404      */
00405     public function disableMoveJsFromHeaderToFooter() {
00406         $this->moveJsFromHeaderToFooter = FALSE;
00407     }
00408 
00409     /**
00410      * Enables compression of javascript
00411      *
00412      * @param void
00413      * @return void
00414      */
00415     public function enableCompressJavascript() {
00416         $this->compressJavascript = TRUE;
00417     }
00418 
00419     /**
00420      * Disables compression of javascript
00421      *
00422      * @param void
00423      * @return void
00424      */
00425     public function disableCompressJavascript() {
00426         $this->compressJavascript = FALSE;
00427     }
00428 
00429     /**
00430      * Enables compression of css
00431      *
00432      * @param void
00433      * @return void
00434      */
00435     public function enableCompressCss() {
00436         $this->compressCss = TRUE;
00437     }
00438 
00439     /**
00440      * Disables compression of css
00441      *
00442      * @param void
00443      * @return void
00444      */
00445     public function disableCompressCss() {
00446         $this->compressCss = FALSE;
00447     }
00448 
00449     /**
00450      * Enables concatenation of js/css files
00451      *
00452      * @param void
00453      * @return void
00454      */
00455     public function enableConcatenateFiles() {
00456         $this->concatenateFiles = TRUE;
00457     }
00458 
00459     /**
00460      * Disables concatenation of js/css files
00461      *
00462      * @param void
00463      * @return void
00464      */
00465     public function disableConcatenateFiles() {
00466         $this->concatenateFiles = FALSE;
00467     }
00468 
00469     /**
00470      * Sets removal of all line breaks in template
00471      *
00472      * @param void
00473      * @return void
00474      */
00475     public function enableRemoveLineBreaksFromTemplate() {
00476         $this->removeLineBreaksFromTemplate = TRUE;
00477     }
00478 
00479     /**
00480      * Unsets removal of all line breaks in template
00481      *
00482      * @param void
00483      * @return void
00484      */
00485     public function disableRemoveLineBreaksFromTemplate() {
00486         $this->removeLineBreaksFromTemplate = FALSE;
00487     }
00488 
00489     /**
00490      * Enables Debug Mode
00491      * This is a shortcut to switch off all compress/concatenate features to enable easier debug
00492      *
00493      * @param void
00494      * @return void
00495      */
00496     public function enableDebugMode() {
00497         $this->compressJavascript = FALSE;
00498         $this->compressCss = FALSE;
00499         $this->concatenateFiles = FALSE;
00500         $this->removeLineBreaksFromTemplate = FALSE;
00501         $this->enableExtCoreDebug = TRUE;
00502         $this->enableExtJsDebug = TRUE;
00503         $this->enableSvgDebug = TRUE;
00504     }
00505 
00506     /*****************************************************/
00507     /*                                                   */
00508     /*  Public Getters                                   */
00509     /*                                                   */
00510     /*                                                   */
00511     /*****************************************************/
00512 
00513     /**
00514      * Gets the title
00515      *
00516      * @return string $title        title of webpage
00517      */
00518     public function getTitle() {
00519         return $this->title;
00520     }
00521 
00522     /**
00523      * Gets the charSet
00524      *
00525      * @return string $charSet
00526      */
00527     public function getCharSet() {
00528         return $this->charSet;
00529     }
00530 
00531     /**
00532      * Gets the language
00533      *
00534      * @return string $lang
00535      */
00536     public function getLanguage() {
00537         return $this->lang;
00538     }
00539 
00540     /**
00541      * Returns rendering mode XHTML or HTML
00542      *
00543      * @return boolean      TRUE if XHTML, FALSE if HTML
00544      */
00545     public function getRenderXhtml() {
00546         return $this->renderXhtml;
00547     }
00548 
00549     /**
00550      * Gets html tag
00551      *
00552      * @return string $htmlTag  html tag
00553      */
00554     public function getHtmlTag() {
00555         return $this->htmlTag;
00556     }
00557 
00558     /**
00559      * Gets head tag
00560      *
00561      * @return string $tag  head tag
00562      */
00563     public function getHeadTag() {
00564         return $this->headTag;
00565     }
00566 
00567     /**
00568      * Gets favicon
00569      *
00570      * @return string $favIcon
00571      */
00572     public function getFavIcon() {
00573         return $this->favIcon;
00574     }
00575 
00576     /**
00577      * Gets icon mime type
00578      *
00579      * @return string $iconMimeType
00580      */
00581     public function getIconMimeType() {
00582         return $this->iconMimeType;
00583     }
00584 
00585     /**
00586      * Gets base url
00587      *
00588      * @return string $url
00589      */
00590     public function getBaseUrl() {
00591         return $this->baseUrl;
00592     }
00593 
00594     /**
00595      * Gets template file
00596      *
00597      * @return string $file
00598      */
00599     public function getTemplateFile($file) {
00600         return $this->templateFile;
00601     }
00602 
00603     /**
00604      * Gets MoveJsFromHeaderToFooter
00605      *
00606      * @return boolean
00607      */
00608     public function getMoveJsFromHeaderToFooter() {
00609         return $this->moveJsFromHeaderToFooter;
00610     }
00611 
00612     /**
00613      * Gets compress of javascript
00614      *
00615      * @return boolean
00616      */
00617     public function getCompressJavascript() {
00618         return $this->compressJavascript;
00619     }
00620 
00621     /**
00622      * Gets compress of css
00623      *
00624      * @return boolean
00625      */
00626     public function getCompressCss() {
00627         return $this->compressCss;
00628     }
00629 
00630     /**
00631      * Gets concatenate of files
00632      *
00633      * @return boolean
00634      */
00635     public function getConcatenateFiles() {
00636         return $this->concatenateFiles;
00637     }
00638 
00639     /**
00640      * Gets remove of empty lines from template
00641      *
00642      * @return boolean
00643      */
00644     public function getRemoveLineBreaksFromTemplate() {
00645         return $this->removeLineBreaksFromTemplate;
00646     }
00647 
00648     /**
00649      * Gets content for body
00650      *
00651      * @return string
00652      */
00653     public function getBodyContent() {
00654         return $this->bodyContent;
00655     }
00656 
00657     /**
00658      * Gets Path for prototype library (relative to typo3 directory)
00659      *
00660      * @return string
00661      */
00662     public function getPrototypePath() {
00663         return $this->prototypePath;
00664     }
00665 
00666     /**
00667      * Gets Path for scriptaculous library (relative to typo3 directory)
00668      *
00669      * @return string
00670      */
00671     public function getScriptaculousPath() {
00672         return $this->scriptaculousPath;
00673     }
00674 
00675     /**
00676      * Gets Path for Ext Core library (relative to typo3 directory)
00677      *
00678      * @return string
00679      */
00680     public function getExtCorePath() {
00681         return $this->extCorePath;
00682     }
00683 
00684     /**
00685      * Gets Path for ExtJs library (relative to typo3 directory)
00686      *
00687      * @return string
00688      */
00689     public function getExtJsPath() {
00690         return $this->extJsPath;
00691     }
00692 
00693     /**
00694      * Gets Path for SVG library (relative to typo3 directory)
00695      *
00696      * @return string
00697      */
00698     public function getSvgPath() {
00699         return $this->svgPath;
00700     }
00701 
00702     /**
00703      * Gets the inline language labels.
00704      *
00705      * @return array The inline language labels
00706      */
00707     public function getInlineLanguageLabels() {
00708         return $this->inlineLanguageLabels;
00709     }
00710 
00711     /**
00712      * Gets the inline language files
00713      *
00714      * @return array
00715      */
00716     public function getInlineLanguageLabelFiles() {
00717         return $this->inlineLanguageLabelFiles;
00718     }
00719 
00720     /*****************************************************/
00721     /*                                                   */
00722     /*  Public Function to add Data                      */
00723     /*                                                   */
00724     /*                                                   */
00725     /*****************************************************/
00726 
00727     /**
00728      * Adds meta data
00729      *
00730      * @param string $meta  meta data (complete metatag)
00731      * @return void
00732      */
00733     public function addMetaTag($meta) {
00734         if (!in_array($meta, $this->metaTags)) {
00735             $this->metaTags[] = $meta;
00736         }
00737     }
00738 
00739     /**
00740      * Adds inline HTML comment
00741      *
00742      * @param string $comment
00743      * @return void
00744      */
00745     public function addInlineComment($comment) {
00746         if (!in_array($comment, $this->inlineComments)) {
00747             $this->inlineComments[] = $comment;
00748         }
00749     }
00750 
00751     /**
00752      * Adds header data
00753      *
00754      * @param string $data   free header data for HTML header
00755      * @return void
00756      */
00757     public function addHeaderData($data) {
00758         if (!in_array($data, $this->headerData)) {
00759             $this->headerData[] = $data;
00760         }
00761     }
00762 
00763     /**
00764      * Adds footer data
00765      *
00766      * @param string $data   free header data for HTML header
00767      * @return void
00768      */
00769     public function addFooterData($data) {
00770         if (!in_array($data, $this->footerData)) {
00771             $this->footerData[] = $data;
00772         }
00773     }
00774 
00775     /* Javascript Files */
00776 
00777     /**
00778      * Adds JS Library. JS Library block is rendered on top of the JS files.
00779      *
00780      * @param string $name
00781      * @param string $file
00782      * @param string $type
00783      * @param boolean $compress     flag if library should be compressed
00784      * @param boolean $forceOnTop   flag if added library should be inserted at begin of this block
00785      * @param string $allWrap
00786      * @return void
00787      */
00788     public function addJsLibrary($name, $file, $type = 'text/javascript', $compress = FALSE, $forceOnTop = FALSE, $allWrap = '') {
00789         if (!$type) {
00790             $type = 'text/javascript';
00791         }
00792         if (!in_array(strtolower($name), $this->jsLibs)) {
00793             $this->jsLibs[strtolower($name)] = array(
00794                 'file' => $file,
00795                 'type' => $type,
00796                 'section' => self::PART_HEADER,
00797                 'compress' => $compress,
00798                 'forceOnTop' => $forceOnTop,
00799                 'allWrap' => $allWrap
00800             );
00801         }
00802 
00803     }
00804 
00805     /**
00806      * Adds JS Library to Footer. JS Library block is rendered on top of the Footer JS files.
00807      *
00808      * @param string $name
00809      * @param string $file
00810      * @param string $type
00811      * @param boolean $compress flag if library should be compressed
00812      * @param boolean $forceOnTop   flag if added library should be inserted at begin of this block
00813      * @param string $allWrap
00814      * @return void
00815      */
00816     public function addJsFooterLibrary($name, $file, $type = 'text/javascript', $compress = FALSE, $forceOnTop = FALSE, $allWrap = '') {
00817         if (!$type) {
00818             $type = 'text/javascript';
00819         }
00820         if (!in_array(strtolower($name), $this->jsLibs)) {
00821             $this->jsLibs[strtolower($name)] = array(
00822                 'file' => $file,
00823                 'type' => $type,
00824                 'section' => self::PART_FOOTER,
00825                 'compress' => $compress,
00826                 'forceOnTop' => $forceOnTop,
00827                 'allWrap' => $allWrap
00828             );
00829         }
00830 
00831     }
00832 
00833     /**
00834      * Adds JS file
00835      *
00836      * @param string $file
00837      * @param string $type
00838      * @param boolean $compress
00839      * @param boolean $forceOnTop
00840      * @param string $allWrap
00841      * @return void
00842      */
00843     public function addJsFile($file, $type = 'text/javascript', $compress = TRUE, $forceOnTop = FALSE, $allWrap = '') {
00844         if (!$type) {
00845             $type = 'text/javascript';
00846         }
00847         if (!isset($this->jsFiles[$file])) {
00848             $this->jsFiles[$file] = array(
00849                 'type' => $type,
00850                 'section' => self::PART_HEADER,
00851                 'compress' => $compress,
00852                 'forceOnTop' => $forceOnTop,
00853                 'allWrap' => $allWrap
00854             );
00855         }
00856     }
00857 
00858     /**
00859      * Adds JS file to footer
00860      *
00861      * @param string $file
00862      * @param string $type
00863      * @param boolean $compress
00864      * @param boolean $forceOnTop
00865      * @return void
00866      */
00867     public function addJsFooterFile($file, $type = 'text/javascript', $compress = TRUE, $forceOnTop = FALSE, $allWrap = '') {
00868         if (!$type) {
00869             $type = 'text/javascript';
00870         }
00871         if (!isset($this->jsFiles[$file])) {
00872             $this->jsFiles[$file] = array(
00873                 'type' => $type,
00874                 'section' => self::PART_FOOTER,
00875                 'compress' => $compress,
00876                 'forceOnTop' => $forceOnTop,
00877                 'allWrap' => $allWrap
00878             );
00879         }
00880     }
00881 
00882     /*Javascript Inline Blocks */
00883 
00884     /**
00885      * Adds JS inline code
00886      *
00887      * @param string $name
00888      * @param string $block
00889      * @param boolean $compress
00890      * @param boolean $forceOnTop
00891      * @return void
00892      */
00893     public function addJsInlineCode($name, $block, $compress = TRUE, $forceOnTop = FALSE) {
00894         if (!isset($this->jsInline[$name]) && !empty($block)) {
00895             $this->jsInline[$name] = array(
00896                 'code' => $block . LF,
00897                 'section' => self::PART_HEADER,
00898                 'compress' => $compress,
00899                 'forceOnTop' => $forceOnTop
00900             );
00901         }
00902     }
00903 
00904     /**
00905      * Adds JS inline code to footer
00906      *
00907      * @param string $name
00908      * @param string $block
00909      * @param boolean $compress
00910      * @param boolean $forceOnTop
00911      * @return void
00912      */
00913     public function addJsFooterInlineCode($name, $block, $compress = TRUE, $forceOnTop = FALSE) {
00914         if (!isset($this->jsInline[$name]) && !empty($block)) {
00915             $this->jsInline[$name] = array(
00916                 'code' => $block . LF,
00917                 'section' => self::PART_FOOTER,
00918                 'compress' => $compress,
00919                 'forceOnTop' => $forceOnTop
00920             );
00921         }
00922     }
00923 
00924     /**
00925      * Adds Ext.onready code, which will be wrapped in Ext.onReady(function() {...});
00926      *
00927      * @param string $block javascript code
00928      * @param boolean $forceOnTop position of the javascript code (TRUE for putting it on top, default is FALSE = bottom)
00929      * @return void
00930      */
00931     public function addExtOnReadyCode($block, $forceOnTop = FALSE) {
00932         if (!in_array($block, $this->extOnReadyCode)) {
00933             if ($forceOnTop) {
00934                 array_unshift($this->extOnReadyCode, $block);
00935             } else {
00936                 $this->extOnReadyCode[] = $block;
00937             }
00938         }
00939     }
00940 
00941     /**
00942      * Adds the ExtDirect code
00943      *
00944      * @param array $filterNamespaces  limit the output to defined namespaces. If empty, all namespaces are generated
00945      * @return void
00946      */
00947     public function addExtDirectCode(array $filterNamespaces = array()) {
00948         if ($this->extDirectCodeAdded) {
00949             return;
00950         }
00951         $this->extDirectCodeAdded = TRUE;
00952 
00953         if (count($filterNamespaces) === 0) {
00954             $filterNamespaces = array('TYPO3');
00955         }
00956 
00957             // for ExtDirect we need flash message support
00958         $this->addJsFile(t3lib_div::resolveBackPath($this->backPath . '../t3lib/js/extjs/ux/flashmessages.js'));
00959 
00960             // add language labels for ExtDirect
00961         if (TYPO3_MODE === 'FE') {
00962             $this->addInlineLanguageLabelArray(array(
00963                 'extDirect_timeoutHeader' => $GLOBALS['TSFE']->sL('LLL:EXT:lang/locallang_misc.xml:extDirect_timeoutHeader'),
00964                 'extDirect_timeoutMessage' => $GLOBALS['TSFE']->sL('LLL:EXT:lang/locallang_misc.xml:extDirect_timeoutMessage'),
00965             ));
00966         } else {
00967             $this->addInlineLanguageLabelArray(array(
00968                 'extDirect_timeoutHeader' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_misc.xml:extDirect_timeoutHeader'),
00969                 'extDirect_timeoutMessage' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_misc.xml:extDirect_timeoutMessage'),
00970             ));
00971         }
00972 
00973         $token = $api = '';
00974         if (TYPO3_MODE === 'BE') {
00975             $formprotection = t3lib_formprotection_Factory::get();
00976             $token = $formprotection->generateToken('extDirect');
00977         }
00978 
00979         /** @var $extDirect t3lib_extjs_ExtDirectApi */
00980         $extDirect = t3lib_div::makeInstance('t3lib_extjs_ExtDirectApi');
00981         $api = $extDirect->getApiPhp($filterNamespaces);
00982         if ($api) {
00983             $this->addJsInlineCode('TYPO3ExtDirectAPI', $api);
00984         }
00985             // Note: we need to iterate thru the object, because the addProvider method
00986             // does this only with multiple arguments
00987         $this->addExtOnReadyCode('
00988             (function() {
00989                 TYPO3.ExtDirectToken = "' . $token . '-extDirect";
00990                 for (var api in Ext.app.ExtDirectAPI) {
00991                     var provider = Ext.Direct.addProvider(Ext.app.ExtDirectAPI[api]);
00992                     provider.on("beforecall", function(provider, transaction, meta) {
00993                         if (transaction.data) {
00994                             transaction.data[transaction.data.length] = TYPO3.ExtDirectToken;
00995                         } else {
00996                             transaction.data = [TYPO3.ExtDirectToken];
00997                         }
00998                     });
00999 
01000                     provider.on("call", function(provider, transaction, meta) {
01001                         if (transaction.isForm) {
01002                             transaction.params.securityToken = TYPO3.ExtDirectToken;
01003                         }
01004                     });
01005                 }
01006             })();
01007 
01008             var extDirectDebug = function(message, header, group) {
01009                 var TYPO3ViewportInstance = null;
01010 
01011                 if (top && top.TYPO3 && typeof top.TYPO3.Backend === "object") {
01012                     TYPO3ViewportInstance = top.TYPO3.Backend;
01013                 } else if (typeof TYPO3 === "object" && typeof TYPO3.Backend === "object") {
01014                     TYPO3ViewportInstance = TYPO3.Backend;
01015                 }
01016 
01017                 if (TYPO3ViewportInstance !== null) {
01018                     TYPO3ViewportInstance.DebugConsole.addTab(message, header, group);
01019                 } else if (typeof console === "object") {
01020                     console.log(message);
01021                 } else {
01022                     document.write(message);
01023                 }
01024             };
01025 
01026             Ext.Direct.on("exception", function(event) {
01027                 if (event.code === Ext.Direct.exceptions.TRANSPORT && !event.where) {
01028                     TYPO3.Flashmessage.display(
01029                         TYPO3.Severity.error,
01030                         TYPO3.lang.extDirect_timeoutHeader,
01031                         TYPO3.lang.extDirect_timeoutMessage,
01032                         30
01033                     );
01034                 } else {
01035                     var backtrace = "";
01036                     if (event.code === "parse") {
01037                         extDirectDebug(
01038                             "<p>" + event.xhr.responseText + "<\/p>",
01039                             event.type,
01040                             "ExtDirect - Exception"
01041                         );
01042                     } else if (event.code === "router") {
01043                         TYPO3.Flashmessage.display(
01044                             TYPO3.Severity.error,
01045                             event.code,
01046                             event.message,
01047                             30
01048                         );
01049                     } else if (event.where) {
01050                         backtrace = "<p style=\"margin-top: 20px;\">" +
01051                             "<strong>Backtrace:<\/strong><br \/>" +
01052                             event.where.replace(/#/g, "<br \/>#") +
01053                             "<\/p>";
01054                         extDirectDebug(
01055                             "<p>" + event.message + "<\/p>" + backtrace,
01056                             event.method,
01057                             "ExtDirect - Exception"
01058                         );
01059                     }
01060 
01061 
01062                 }
01063             });
01064 
01065             Ext.Direct.on("event", function(event, provider) {
01066                 if (typeof event.debug !== "undefined" && event.debug !== "") {
01067                     extDirectDebug(event.debug, event.method, "ExtDirect - Debug");
01068                 }
01069             });
01070             ',
01071             TRUE
01072         );
01073     }
01074 
01075     /* CSS Files */
01076 
01077     /**
01078      * Adds CSS file
01079      *
01080      * @param string $file
01081      * @param string $rel
01082      * @param string $media
01083      * @param string $title
01084      * @param boolean $compress
01085      * @param boolean $forceOnTop
01086      * @return void
01087      */
01088     public function addCssFile($file, $rel = 'stylesheet', $media = 'all', $title = '', $compress = TRUE, $forceOnTop = FALSE, $allWrap = '') {
01089         if (!isset($this->cssFiles[$file])) {
01090             $this->cssFiles[$file] = array(
01091                 'rel' => $rel,
01092                 'media' => $media,
01093                 'title' => $title,
01094                 'compress' => $compress,
01095                 'forceOnTop' => $forceOnTop,
01096                 'allWrap' => $allWrap
01097             );
01098         }
01099     }
01100 
01101     /*CSS Inline Blocks */
01102 
01103     /**
01104      * Adds CSS inline code
01105      *
01106      * @param string $name
01107      * @param string $block
01108      * @param boolean $compress
01109      * @param boolean $forceOnTop
01110      * @return void
01111      */
01112     public function addCssInlineBlock($name, $block, $compress = FALSE, $forceOnTop = FALSE) {
01113         if (!isset($this->cssInline[$name]) && !empty($block)) {
01114             $this->cssInline[$name] = array(
01115                 'code' => $block,
01116                 'compress' => $compress,
01117                 'forceOnTop' => $forceOnTop
01118             );
01119         }
01120     }
01121 
01122     /* JS Libraries */
01123 
01124     /**
01125      *  call function if you need the prototype library
01126      *
01127      * @return void
01128      */
01129     public function loadPrototype() {
01130         $this->addPrototype = TRUE;
01131     }
01132 
01133     /**
01134      * call function if you need the Scriptaculous library
01135      *
01136      * @param string $modules   add modules you need. use "all" if you need complete modules
01137      * @return void
01138      */
01139     public function loadScriptaculous($modules = 'all') {
01140             // Scriptaculous require prototype, so load prototype too.
01141         $this->addPrototype = TRUE;
01142         $this->addScriptaculous = TRUE;
01143         if ($modules) {
01144             if ($modules == 'all') {
01145                 foreach ($this->addScriptaculousModules as $key => $value) {
01146                     $this->addScriptaculousModules[$key] = TRUE;
01147                 }
01148             } else {
01149                 $mods = t3lib_div::trimExplode(',', $modules);
01150                 foreach ($mods as $mod) {
01151                     if (isset($this->addScriptaculousModules[strtolower($mod)])) {
01152                         $this->addScriptaculousModules[strtolower($mod)] = TRUE;
01153                     }
01154                 }
01155             }
01156         }
01157     }
01158 
01159     /**
01160      * call this function if you need the extJS library
01161      *
01162      * @param boolean $css flag, if set the ext-css will be loaded
01163      * @param boolean $theme flag, if set the ext-theme "grey" will be loaded
01164      * @param string $adapter choose alternative adapter, possible values: yui, prototype, jquery
01165      * @return void
01166      */
01167     public function loadExtJS($css = TRUE, $theme = TRUE, $adapter = '') {
01168         if ($adapter) {
01169                 // empty $adapter will always load the ext adapter
01170             switch (t3lib_div::strtolower(trim($adapter))) {
01171                 case self::EXTJS_ADAPTER_YUI :
01172                     $this->extJSadapter = 'yui/ext-yui-adapter.js';
01173                 break;
01174                 case self::EXTJS_ADAPTER_PROTOTYPE :
01175                     $this->extJSadapter = 'prototype/ext-prototype-adapter.js';
01176                 break;
01177                 case self::EXTJS_ADAPTER_JQUERY :
01178                     $this->extJSadapter = 'jquery/ext-jquery-adapter.js';
01179                 break;
01180             }
01181         }
01182         $this->addExtJS = TRUE;
01183         $this->extJStheme = $theme;
01184         $this->extJScss = $css;
01185 
01186     }
01187 
01188     /**
01189      * Enables ExtJs QuickTips
01190      * Need extJs loaded
01191      *
01192      * @return void
01193      *
01194      */
01195     public function enableExtJSQuickTips() {
01196         $this->enableExtJSQuickTips = TRUE;
01197     }
01198 
01199 
01200     /**
01201      * call function if you need the ExtCore library
01202      *
01203      * @return void
01204      */
01205     public function loadExtCore() {
01206         $this->addExtCore = TRUE;
01207     }
01208 
01209     /**
01210      * call function if you need the SVG library
01211      *
01212      * @return void
01213      */
01214     public function loadSvg() {
01215         $this->addSvg = TRUE;
01216     }
01217 
01218     /**
01219      * call this function to load debug version of ExtJS. Use this for development only
01220      *
01221      */
01222     public function enableSvgDebug() {
01223         $this->enableSvgDebug = TRUE;
01224     }
01225 
01226     /**
01227      * call this function to force flash usage with SVG library
01228      *
01229      */
01230     public function svgForceFlash() {
01231         $this->addMetaTag('<meta name="svg.render.forceflash" content="true" />');
01232     }
01233 
01234     /**
01235      * call this function to load debug version of ExtJS. Use this for development only
01236      *
01237      */
01238     public function enableExtJsDebug() {
01239         $this->enableExtJsDebug = TRUE;
01240     }
01241 
01242     /**
01243      * call this function to load debug version of ExtCore. Use this for development only
01244      *
01245      * @return void
01246      */
01247     public function enableExtCoreDebug() {
01248         $this->enableExtCoreDebug = TRUE;
01249     }
01250 
01251     /**
01252      * Adds Javascript Inline Label. This will occur in TYPO3.lang - object
01253      * The label can be used in scripts with TYPO3.lang.<key>
01254      * Need extJs loaded
01255      *
01256      * @param string $key
01257      * @param string $value
01258      * @return void
01259      */
01260     public function addInlineLanguageLabel($key, $value) {
01261         $this->inlineLanguageLabels[$key] = $value;
01262     }
01263 
01264     /**
01265      * Adds Javascript Inline Label Array. This will occur in TYPO3.lang - object
01266      * The label can be used in scripts with TYPO3.lang.<key>
01267      * Array will be merged with existing array.
01268      * Need extJs loaded
01269      *
01270      * @param array $array
01271      * @return void
01272      */
01273     public function addInlineLanguageLabelArray(array $array) {
01274         $this->inlineLanguageLabels = array_merge($this->inlineLanguageLabels, $array);
01275     }
01276 
01277     /**
01278      * Gets labels to be used in JavaScript fetched from a locallang file.
01279      *
01280      * @param   string      Input is a file-reference (see t3lib_div::getFileAbsFileName). That file is expected to be a 'locallang.xml' file containing a valid XML TYPO3 language structure.
01281      * @param   string      $selectionPrefix: Prefix to select the correct labels (default: '')
01282      * @param   string      $stripFromSelectionName: Sub-prefix to be removed from label names in the result (default: '')
01283      * @param   integer     Error mode (when file could not be found): 0 - syslog entry, 1 - do nothing, 2 - throw an exception
01284      * @return  void
01285      */
01286     public function addInlineLanguageLabelFile($fileRef, $selectionPrefix = '', $stripFromSelectionName = '', $errorMode = 0) {
01287         $index = md5($fileRef . $selectionPrefix . $stripFromSelectionName);
01288         if ($fileRef && !isset($this->inlineLanguageLabelFiles[$index])) {
01289             $this->inlineLanguageLabelFiles[$index] = array(
01290                 'fileRef' => $fileRef,
01291                 'selectionPrefix' => $selectionPrefix,
01292                 'stripFromSelectionName' => $stripFromSelectionName,
01293                 'errorMode' => $errorMode
01294             );
01295         }
01296     }
01297 
01298 
01299     /**
01300      * Adds Javascript Inline Setting. This will occur in TYPO3.settings - object
01301      * The label can be used in scripts with TYPO3.setting.<key>
01302      * Need extJs loaded
01303      *
01304      * @param string $namespace
01305      * @param string $key
01306      * @param string $value
01307      * @return void
01308      */
01309     public function addInlineSetting($namespace, $key, $value) {
01310         if ($namespace) {
01311             if (strpos($namespace, '.')) {
01312                 $parts = explode('.', $namespace);
01313                 $a = &$this->inlineSettings;
01314                 foreach ($parts as $part) {
01315                     $a = &$a[$part];
01316                 }
01317                 $a[$key] = $value;
01318             } else {
01319                 $this->inlineSettings[$namespace][$key] = $value;
01320             }
01321         } else {
01322             $this->inlineSettings[$key] = $value;
01323         }
01324     }
01325 
01326     /**
01327      * Adds Javascript Inline Setting. This will occur in TYPO3.settings - object
01328      * The label can be used in scripts with TYPO3.setting.<key>
01329      * Array will be merged with existing array.
01330      * Need extJs loaded
01331      *
01332      * @param string $namespace
01333      * @param array $array
01334      * @return void
01335      */
01336     public function addInlineSettingArray($namespace, array $array) {
01337         if ($namespace) {
01338             if (strpos($namespace, '.')) {
01339                 $parts = explode('.', $namespace);
01340                 $a = &$this->inlineSettings;
01341                 foreach ($parts as $part) {
01342                     $a = &$a[$part];
01343                 }
01344                 $a = array_merge((array) $a, $array);
01345             } else {
01346                 $this->inlineSettings[$namespace] = array_merge((array) $this->inlineSettings[$namespace], $array);
01347             }
01348         } else {
01349             $this->inlineSettings = array_merge($this->inlineSettings, $array);
01350         }
01351     }
01352 
01353     /**
01354      * Adds content to body content
01355      *
01356      * @param string $content
01357      * @return void
01358      */
01359     public function addBodyContent($content) {
01360         $this->bodyContent .= $content;
01361     }
01362 
01363     /*****************************************************/
01364     /*                                                   */
01365     /*  Render Functions                                 */
01366     /*                                                   */
01367     /*                                                   */
01368     /*****************************************************/
01369 
01370     /**
01371      * render the section (Header or Footer)
01372      *
01373      * @param int $part section which should be rendered: self::PART_COMPLETE, self::PART_HEADER or self::PART_FOOTER
01374      * @return string   content of rendered section
01375      */
01376     public function render($part = self::PART_COMPLETE) {
01377 
01378         $jsFiles = '';
01379         $cssFiles = '';
01380         $cssInline = '';
01381         $jsInline = '';
01382         $jsFooterInline = '';
01383         $jsFooterLibs = '';
01384         $jsFooterFiles = '';
01385 
01386             // preRenderHook for possible manuipulation
01387         if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_pagerenderer.php']['render-preProcess'])) {
01388             $params = array(
01389                 'jsLibs' => &$this->jsLibs,
01390                 'jsFooterLibs'   => &$this->jsFooterLibs,
01391                 'jsFiles' => &$this->jsFiles,
01392                 'jsFooterFiles' => &$this->jsFooterFiles,
01393                 'cssFiles' => &$this->cssFiles,
01394                 'headerData' => &$this->headerData,
01395                 'footerData' => &$this->footerData,
01396                 'jsInline' => &$this->jsInline,
01397                 'jsFooterInline' => &$this->jsFooterInline,
01398                 'cssInline' => &$this->cssInline,
01399             );
01400             foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_pagerenderer.php']['render-preProcess'] as $hook) {
01401                 t3lib_div::callUserFunction($hook, $params, $this);
01402             }
01403         }
01404 
01405         $jsLibs = $this->renderJsLibraries();
01406 
01407         if ($this->concatenateFiles) {
01408                 // do the file concatenation
01409             $this->doConcatenate();
01410         }
01411         if ($this->compressCss || $this->compressJavascript) {
01412                 // do the file compression
01413             $this->doCompress();
01414         }
01415 
01416         $metaTags = implode(LF, $this->metaTags);
01417 
01418             // remove ending slashes from static header block
01419             // if the page is beeing rendered as html (not xhtml)
01420             // and define variable $endingSlash for further use
01421         if ($this->getRenderXhtml()) {
01422             $endingSlash = ' /';
01423         } else {
01424             $this->metaCharsetTag = str_replace(' />', '>', $this->metaCharsetTag);
01425             $this->baseUrlTag = str_replace(' />', '>', $this->baseUrlTag);
01426             $this->shortcutTag = str_replace(' />', '>', $this->shortcutTag);
01427             $endingSlash = '';
01428         }
01429 
01430         if (count($this->cssFiles)) {
01431             foreach ($this->cssFiles as $file => $properties) {
01432                 $file = t3lib_div::resolveBackPath($file);
01433                 $file = t3lib_div::createVersionNumberedFilename($file);
01434                 $tag = '<link rel="' . htmlspecialchars($properties['rel']) . '" type="text/css" href="' .
01435                        htmlspecialchars($file) . '" media="' . htmlspecialchars($properties['media']) . '"' .
01436                        ($properties['title'] ? ' title="' . htmlspecialchars($properties['title']) . '"' : '') .
01437                        $endingSlash . '>';
01438                 if ($properties['allWrap'] && strpos($properties['allWrap'], '|') !== FALSE) {
01439                     $tag = str_replace('|', $tag, $properties['allWrap']);
01440                 }
01441                 if ($properties['forceOnTop']) {
01442                     $cssFiles = $tag . LF . $cssFiles;
01443                 } else {
01444                     $cssFiles .= LF . $tag;
01445                 }
01446             }
01447         }
01448 
01449         if (count($this->cssInline)) {
01450             foreach ($this->cssInline as $name => $properties) {
01451                 if ($properties['forceOnTop']) {
01452                     $cssInline = '/*' . htmlspecialchars($name) . '*/' . LF . $properties['code'] . LF . $cssInline;
01453                 } else {
01454                     $cssInline .= '/*' . htmlspecialchars($name) . '*/' . LF . $properties['code'] . LF;
01455                 }
01456             }
01457             $cssInline = $this->inlineCssWrap[0] . $cssInline . $this->inlineCssWrap[1];
01458         }
01459 
01460         if (count($this->jsLibs)) {
01461             foreach ($this->jsLibs as $name => $properties) {
01462                 $properties['file'] = t3lib_div::resolveBackPath($properties['file']);
01463                 $properties['file'] = t3lib_div::createVersionNumberedFilename($properties['file']);
01464                 $tag = '<script src="' . htmlspecialchars($properties['file']) . '" type="' . htmlspecialchars($properties['type']) . '"></script>';
01465                 if ($properties['allWrap'] && strpos($properties['allWrap'], '|') !== FALSE) {
01466                     $tag = str_replace('|', $tag, $properties['allWrap']);
01467                 }
01468                 if ($properties['forceOnTop']) {
01469                     if ($properties['section'] === self::PART_HEADER) {
01470                         $jsLibs = $tag . LF . $jsLibs;
01471                     } else {
01472                         $jsFooterLibs = $tag . LF . $jsFooterLibs;
01473                     }
01474                 } else {
01475                     if ($properties['section'] === self::PART_HEADER) {
01476                         $jsLibs .= LF . $tag;
01477                     } else {
01478                         $jsFooterLibs .= LF . $tag;
01479                     }
01480                 }
01481             }
01482         }
01483 
01484         if (count($this->jsFiles)) {
01485             foreach ($this->jsFiles as $file => $properties) {
01486                 $file = t3lib_div::resolveBackPath($file);
01487                 $file = t3lib_div::createVersionNumberedFilename($file);
01488                 $tag = '<script src="' . htmlspecialchars($file) . '" type="' . htmlspecialchars($properties['type']) . '"></script>';
01489                 if ($properties['allWrap'] && strpos($properties['allWrap'], '|') !== FALSE) {
01490                     $tag = str_replace('|', $tag, $properties['allWrap']);
01491                 }
01492                 if ($properties['forceOnTop']) {
01493                     if ($properties['section'] === self::PART_HEADER) {
01494                         $jsFiles = $tag . LF . $jsFiles;
01495                     } else {
01496                         $jsFooterFiles = $tag . LF . $jsFooterFiles;
01497                     }
01498                 } else {
01499                     if ($properties['section'] === self::PART_HEADER) {
01500                         $jsFiles .= LF . $tag;
01501                     } else {
01502                         $jsFooterFiles .= LF . $tag;
01503                     }
01504                 }
01505             }
01506         }
01507 
01508         if (count($this->jsInline)) {
01509             foreach ($this->jsInline as $name => $properties) {
01510                 if ($properties['forceOnTop']) {
01511                     if ($properties['section'] === self::PART_HEADER) {
01512                         $jsInline = '/*' . htmlspecialchars($name) . '*/' . LF . $properties['code'] . LF . $jsInline;
01513                     } else {
01514                         $jsFooterInline = '/*' . htmlspecialchars($name) . '*/' . LF . $properties['code'] . LF . $jsFooterInline;
01515                     }
01516                 } else {
01517                     if ($properties['section'] === self::PART_HEADER) {
01518                         $jsInline .= '/*' . htmlspecialchars($name) . '*/' . LF . $properties['code'] . LF;
01519                     } else {
01520                         $jsFooterInline .= '/*' . htmlspecialchars($name) . '*/' . LF . $properties['code'] . LF;
01521                     }
01522                 }
01523             }
01524         }
01525 
01526 
01527         if ($jsInline) {
01528             $jsInline = $this->inlineJavascriptWrap[0] . $jsInline . $this->inlineJavascriptWrap[1];
01529         }
01530 
01531         if ($jsFooterInline) {
01532             $jsFooterInline = $this->inlineJavascriptWrap[0] . $jsFooterInline . $this->inlineJavascriptWrap[1];
01533         }
01534 
01535 
01536             // get template
01537         $templateFile = t3lib_div::getFileAbsFileName($this->templateFile, TRUE);
01538         $template = t3lib_div::getURL($templateFile);
01539 
01540         if ($this->removeLineBreaksFromTemplate) {
01541             $template = strtr($template, array(LF => '', CR => ''));
01542         }
01543         if ($part != self::PART_COMPLETE) {
01544             $templatePart = explode('###BODY###', $template);
01545             $template = $templatePart[$part - 1];
01546         }
01547 
01548         if ($this->moveJsFromHeaderToFooter) {
01549             $jsFooterLibs = $jsLibs . LF . $jsFooterLibs;
01550             $jsLibs = '';
01551             $jsFooterFiles = $jsFiles . LF . $jsFooterFiles;
01552             $jsFiles = '';
01553             $jsFooterInline = $jsInline . LF . $jsFooterInline;
01554             $jsInline = '';
01555         }
01556 
01557             // postRenderHook for possible manipulation
01558         if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_pagerenderer.php']['render-postProcess'])) {
01559             $params = array (
01560                 'jsLibs'               => &$jsLibs,
01561                 'jsFiles'              => &$jsFiles,
01562                 'jsFooterFiles'        => &$jsFooterFiles,
01563                 'cssFiles'             => &$cssFiles,
01564                 'headerData'           => &$this->headerData,
01565                 'footerData'           => &$this->footerData,
01566                 'jsInline'             => &$jsInline,
01567                 'cssInline'            => &$cssInline,
01568                 'xmlPrologAndDocType'  => &$this->xmlPrologAndDocType,
01569                 'htmlTag'              => &$this->htmlTag,
01570                 'headTag'              => &$this->headTag,
01571                 'charSet'              => &$this->charSet,
01572                 'metaCharsetTag'       => &$this->metaCharsetTag,
01573                 'shortcutTag'          => &$this->shortcutTag,
01574                 'inlineComments'       => &$this->inlineComments,
01575                 'baseUrl'              => &$this->baseUrl,
01576                 'baseUrlTag'           => &$this->baseUrlTag,
01577                 'favIcon'              => &$this->favIcon,
01578                 'iconMimeType'         => &$this->iconMimeType,
01579                 'titleTag'             => &$this->titleTag,
01580                 'title'                => &$this->title,
01581                 'metaTags'             => &$metaTags,
01582                 'jsFooterInline'       => &$jsFooterInline,
01583                 'jsFooterLibs'         => &$jsFooterLibs,
01584                 'bodyContent'          => &$this->bodyContent,
01585             );
01586             foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_pagerenderer.php']['render-postProcess'] as $hook) {
01587                 t3lib_div::callUserFunction($hook, $params, $this);
01588             }
01589         }
01590 
01591         $markerArray = array(
01592             'XMLPROLOG_DOCTYPE' => $this->xmlPrologAndDocType,
01593             'HTMLTAG'           => $this->htmlTag,
01594             'HEADTAG'           => $this->headTag,
01595             'METACHARSET'       => $this->charSet ? str_replace('|', htmlspecialchars($this->charSet), $this->metaCharsetTag) : '',
01596             'INLINECOMMENT'     => $this->inlineComments ? LF . LF . '<!-- ' . LF . implode(LF, $this->inlineComments) . '-->' . LF . LF : '',
01597             'BASEURL'           => $this->baseUrl ? str_replace('|', $this->baseUrl, $this->baseUrlTag) : '',
01598             'SHORTCUT'          => $this->favIcon ? sprintf($this->shortcutTag, htmlspecialchars($this->favIcon), $this->iconMimeType) : '',
01599             'CSS_INCLUDE'       => $cssFiles,
01600             'CSS_INLINE'        => $cssInline,
01601             'JS_INLINE'         => $jsInline,
01602             'JS_INCLUDE'        => $jsFiles,
01603             'JS_LIBS'           => $jsLibs,
01604             'TITLE'             => $this->title ? str_replace('|', htmlspecialchars($this->title), $this->titleTag) : '',
01605             'META'              => $metaTags,
01606             'HEADERDATA'        => $this->headerData ? implode(LF, $this->headerData) : '',
01607             'FOOTERDATA'        => $this->footerData ? implode(LF, $this->footerData) : '',
01608             'JS_LIBS_FOOTER'    => $jsFooterLibs,
01609             'JS_INCLUDE_FOOTER' => $jsFooterFiles,
01610             'JS_INLINE_FOOTER'  => $jsFooterInline,
01611             'BODY'              => $this->bodyContent,
01612         );
01613 
01614         $markerArray = array_map('trim', $markerArray);
01615 
01616         $this->reset();
01617         return trim(t3lib_parsehtml::substituteMarkerArray($template, $markerArray, '###|###'));
01618     }
01619 
01620     /**
01621      * helper function for render the javascript libraries
01622      *
01623      * @return string   content with javascript libraries
01624      */
01625     protected function renderJsLibraries() {
01626         $out = '';
01627 
01628         if ($this->addSvg) {
01629             $out .= '<script src="' . $this->processJsFile($this->backPath . $this->svgPath . 'svg.js') .
01630                     '" data-path="' . $this->backPath . $this->svgPath .
01631                     '"' . ($this->enableSvgDebug ? ' data-debug="true"' : '') . '></script>';
01632         }
01633 
01634         if ($this->addPrototype) {
01635             $out .= '<script src="' . $this->processJsFile($this->backPath . $this->prototypePath . 'prototype.js') .
01636                     '" type="text/javascript"></script>' . LF;
01637             unset($this->jsFiles[$this->backPath . $this->prototypePath . 'prototype.js']);
01638         }
01639 
01640         if ($this->addScriptaculous) {
01641             $mods = array();
01642             foreach ($this->addScriptaculousModules as $key => $value) {
01643                 if ($this->addScriptaculousModules[$key]) {
01644                     $mods[] = $key;
01645                 }
01646             }
01647                 // resolve dependencies
01648             if (in_array('dragdrop', $mods) || in_array('controls', $mods)) {
01649                 $mods = array_merge(array('effects'), $mods);
01650             }
01651 
01652             if (count($mods)) {
01653                 foreach ($mods as $module) {
01654                     $out .= '<script src="' . $this->processJsFile($this->backPath .
01655                                                                    $this->scriptaculousPath . $module . '.js') . '" type="text/javascript"></script>' . LF;
01656                     unset($this->jsFiles[$this->backPath . $this->scriptaculousPath . $module . '.js']);
01657                 }
01658             }
01659             $out .= '<script src="' . $this->processJsFile($this->backPath . $this->scriptaculousPath .
01660                                                            'scriptaculous.js') . '" type="text/javascript"></script>' . LF;
01661             unset($this->jsFiles[$this->backPath . $this->scriptaculousPath . 'scriptaculous.js']);
01662         }
01663 
01664             // include extCore
01665         if ($this->addExtCore) {
01666             $out .= '<script src="' . $this->processJsFile($this->backPath .
01667                                                            $this->extCorePath . 'ext-core' . ($this->enableExtCoreDebug ? '-debug' : '') . '.js') .
01668                     '" type="text/javascript"></script>' . LF;
01669             unset($this->jsFiles[$this->backPath . $this->extCorePath . 'ext-core' . ($this->enableExtCoreDebug ? '-debug' : '') . '.js']);
01670         }
01671 
01672             // include extJS
01673         if ($this->addExtJS) {
01674                 // use the base adapter all the time
01675             $out .= '<script src="' . $this->processJsFile($this->backPath . $this->extJsPath .
01676                                                            'adapter/' . ($this->enableExtJsDebug ?
01677                     str_replace('.js', '-debug.js', $this->extJSadapter) : $this->extJSadapter)) .
01678                     '" type="text/javascript"></script>' . LF;
01679             $out .= '<script src="' . $this->processJsFile($this->backPath . $this->extJsPath .
01680                                                            'ext-all' . ($this->enableExtJsDebug ? '-debug' : '') . '.js') .
01681                     '" type="text/javascript"></script>' . LF;
01682 
01683                 // add extJS localization
01684             $localeMap = $this->csConvObj->isoArray; // load standard ISO mapping and modify for use with ExtJS
01685             $localeMap[''] = 'en';
01686             $localeMap['default'] = 'en';
01687             $localeMap['gr'] = 'el_GR'; // Greek
01688             $localeMap['no'] = 'no_BO'; // Norwegian Bokmaal
01689             $localeMap['se'] = 'se_SV'; // Swedish
01690 
01691 
01692             $extJsLang = isset($localeMap[$this->lang]) ? $localeMap[$this->lang] : $this->lang;
01693                 // TODO autoconvert file from UTF8 to current BE charset if necessary!!!!
01694             $extJsLocaleFile = $this->extJsPath . 'locale/ext-lang-' . $extJsLang . '.js';
01695             if (file_exists(PATH_typo3 . $extJsLocaleFile)) {
01696                 $out .= '<script src="' . $this->processJsFile($this->backPath .
01697                                                                $extJsLocaleFile) . '" type="text/javascript" charset="utf-8"></script>' . LF;
01698             }
01699 
01700 
01701                 // remove extjs from JScodeLibArray
01702             unset(
01703             $this->jsFiles[$this->backPath . $this->extJsPath . 'ext-all.js'],
01704             $this->jsFiles[$this->backPath . $this->extJsPath . 'ext-all-debug.js']
01705             );
01706         }
01707 
01708         if (count($this->inlineLanguageLabelFiles)) {
01709             foreach ($this->inlineLanguageLabelFiles as $languageLabelFile) {
01710                 $this->includeLanguageFileForInline(
01711                     $languageLabelFile['fileRef'],
01712                     $languageLabelFile['selectionPrefix'],
01713                     $languageLabelFile['stripFromSelectionName'],
01714                     $languageLabelFile['$errorMode']
01715                 );
01716             }
01717         }
01718         unset($this->inlineLanguageLabelFiles);
01719 
01720             // Convert labels/settings back to UTF-8 since json_encode() only works with UTF-8:
01721         if ($this->getCharSet() !== 'utf-8') {
01722             if ($this->inlineLanguageLabels) {
01723                 $this->csConvObj->convArray($this->inlineLanguageLabels, $this->getCharSet(), 'utf-8');
01724             }
01725             if ($this->inlineSettings) {
01726                 $this->csConvObj->convArray($this->inlineSettings, $this->getCharSet(), 'utf-8');
01727             }
01728         }
01729 
01730         $inlineSettings = $this->inlineLanguageLabels ? 'TYPO3.lang = ' . json_encode($this->inlineLanguageLabels) . ';' : '';
01731         $inlineSettings .= $this->inlineSettings ? 'TYPO3.settings = ' . json_encode($this->inlineSettings) . ';' : '';
01732 
01733         if ($this->addExtCore || $this->addExtJS) {
01734                 // set clear.gif, move it on top, add handler code
01735             $code = '';
01736             if (count($this->extOnReadyCode)) {
01737                 foreach ($this->extOnReadyCode as $block) {
01738                     $code .= $block;
01739                 }
01740             }
01741 
01742             $out .= $this->inlineJavascriptWrap[0] . '
01743                 Ext.ns("TYPO3");
01744                 Ext.BLANK_IMAGE_URL = "' . htmlspecialchars(t3lib_div::locationHeaderUrl($this->backPath . 'gfx/clear.gif')) . '";' . LF .
01745                     $inlineSettings .
01746                     'Ext.onReady(function() {' .
01747                     ($this->enableExtJSQuickTips ? 'Ext.QuickTips.init();' . LF : '') . $code .
01748                     ' });' . $this->inlineJavascriptWrap[1];
01749             unset ($this->extOnReadyCode);
01750 
01751             if ($this->extJStheme) {
01752                 if (isset($GLOBALS['TBE_STYLES']['extJS']['theme'])) {
01753                     $this->addCssFile($this->backPath . $GLOBALS['TBE_STYLES']['extJS']['theme'], 'stylesheet', 'all', '', TRUE, TRUE);
01754                 } else {
01755                     $this->addCssFile($this->backPath . $this->extJsPath . 'resources/css/xtheme-blue.css', 'stylesheet', 'all', '', TRUE, TRUE);
01756                 }
01757             }
01758             if ($this->extJScss) {
01759                 if (isset($GLOBALS['TBE_STYLES']['extJS']['all'])) {
01760                     $this->addCssFile($this->backPath . $GLOBALS['TBE_STYLES']['extJS']['all'], 'stylesheet', 'all', '', TRUE, TRUE);
01761                 } else {
01762                     $this->addCssFile($this->backPath . $this->extJsPath . 'resources/css/ext-all-notheme.css', 'stylesheet', 'all', '', TRUE, TRUE);
01763                 }
01764             }
01765         } else {
01766             if ($inlineSettings) {
01767                 $out .= $this->inlineJavascriptWrap[0] . $inlineSettings . $this->inlineJavascriptWrap[1];
01768             }
01769         }
01770 
01771         return $out;
01772     }
01773 
01774     protected function includeLanguageFileForInline($fileRef, $selectionPrefix = '', $stripFromSelectionName = '', $errorMode = 0) {
01775         if (!isset($this->lang) || !isset($this->charSet)) {
01776             throw new RuntimeException('Language and character encoding are not set.', 1284906026);
01777         }
01778 
01779         $labelsFromFile = array();
01780         $allLabels = t3lib_div::readLLfile($fileRef, $this->lang, $this->charSet, $errorMode);
01781 
01782             // Regular expression to strip the selection prefix and possibly something from the label name:
01783         $labelPattern = '#^' . preg_quote($selectionPrefix, '#') . '(' . preg_quote($stripFromSelectionName, '#') . ')?#';
01784 
01785         if ($allLabels !== FALSE) {
01786                 // Merge language specific translations:
01787             if ($this->lang !== 'default' && isset($allLabels[$this->lang])) {
01788                 $labels = array_merge($allLabels['default'], $allLabels[$this->lang]);
01789             } else {
01790                 $labels = $allLabels['default'];
01791             }
01792 
01793                 // Iterate through all locallang labels:
01794             foreach ($labels as $label => $value) {
01795                 if ($selectionPrefix === '') {
01796                     $labelsFromFile[$label] = $value;
01797                 } elseif (strpos($label, $selectionPrefix) === 0) {
01798                     $key = preg_replace($labelPattern, '', $label);
01799                     $labelsFromFile[$label] = $value;
01800                 }
01801             }
01802 
01803             $this->inlineLanguageLabels = array_merge($this->inlineLanguageLabels, $labelsFromFile);
01804         }
01805     }
01806 
01807     /*****************************************************/
01808     /*                                                   */
01809     /*  Tools                                            */
01810     /*                                                   */
01811     /*                                                   */
01812     /*****************************************************/
01813 
01814     /**
01815      * concatenate files into one file
01816      * registered handler
01817      *
01818      * @return void
01819      */
01820     protected function doConcatenate() {
01821             // traverse the arrays, concatenate in one file
01822             // then remove concatenated files from array and add the concatenated file
01823 
01824         if ($this->concatenateFiles) {
01825             $params = array(
01826                 'jsLibs' => &$this->jsLibs,
01827                 'jsFiles' => &$this->jsFiles,
01828                 'jsFooterFiles' => &$this->jsFooterFiles,
01829                 'cssFiles' => &$this->cssFiles,
01830                 'headerData' => &$this->headerData,
01831                 'footerData' => &$this->footerData,
01832             );
01833 
01834             if ($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['concatenateHandler']) {
01835                     // use extern concatenate routine
01836                 t3lib_div::callUserFunction($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['concatenateHandler'], $params, $this);
01837             } elseif (TYPO3_MODE === 'BE') {
01838                 $cssOptions = array('baseDirectories' => $GLOBALS['TBE_TEMPLATE']->getSkinStylesheetDirectories());
01839                 $this->cssFiles = $this->getCompressor()->concatenateCssFiles($this->cssFiles, $cssOptions);
01840             }
01841         }
01842     }
01843 
01844     /**
01845      * compress inline code
01846      *
01847      * @return void
01848      */
01849     protected function doCompress() {
01850 
01851         if ($this->compressJavascript && $GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['jsCompressHandler']) {
01852                 // use extern compress routine
01853             $params = array(
01854                 'jsInline' => &$this->jsInline,
01855                 'jsFooterInline' => &$this->jsFooterInline,
01856                 'jsLibs' => &$this->jsLibs,
01857                 'jsFiles' => &$this->jsFiles,
01858                 'jsFooterFiles' => &$this->jsFooterFiles,
01859                 'headerData' => &$this->headerData,
01860                 'footerData' => &$this->footerData,
01861             );
01862             t3lib_div::callUserFunction($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['jsCompressHandler'], $params, $this);
01863         } else {
01864                 // traverse the arrays, compress files
01865 
01866             if ($this->compressJavascript) {
01867                 if (count($this->jsInline)) {
01868                     foreach ($this->jsInline as $name => $properties) {
01869                         if ($properties['compress']) {
01870                             $error = '';
01871                             $this->jsInline[$name]['code'] = t3lib_div::minifyJavaScript($properties['code'], $error);
01872                             if ($error) {
01873                                 $this->compressError .= 'Error with minify JS Inline Block "' . $name . '": ' . $error . LF;
01874                             }
01875                         }
01876                     }
01877                 }
01878                 if (TYPO3_MODE === 'BE') {
01879                     $this->jsFiles = $this->getCompressor()->compressJsFiles($this->jsFiles);
01880                     $this->jsFooterFiles = $this->getCompressor()->compressJsFiles($this->jsFooterFiles);
01881                 }
01882             }
01883         }
01884         if ($this->compressCss) {
01885                 // use extern compress routine
01886             $params = array(
01887                 'cssInline' => &$this->cssInline,
01888                 'cssFiles' => &$this->cssFiles,
01889                 'headerData' => &$this->headerData,
01890                 'footerData' => &$this->footerData,
01891             );
01892 
01893             if ($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['cssCompressHandler']) {
01894                     // use extern concatenate routine
01895                 t3lib_div::callUserFunction($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['cssCompressHandler'], $params, $this);
01896             } elseif (TYPO3_MODE === 'BE') {
01897                 $this->cssFiles = $this->getCompressor()->compressCssFiles($this->cssFiles);
01898             }
01899         }
01900     }
01901 
01902     /**
01903      * Returns instance of t3lib_Compressor
01904      *
01905      * @return  t3lib_Compressor        Instance of t3lib_Compressor
01906      */
01907     protected function getCompressor() {
01908         if ($this->compressor === NULL) {
01909             $this->compressor = t3lib_div::makeInstance('t3lib_Compressor');
01910         }
01911         return $this->compressor;
01912     }
01913 
01914     /**
01915      * Processes a Javascript file dependent on the current context
01916      *
01917      * Adds the version number for Frontend, compresses the file for Backend
01918      *
01919      * @param   string  $filename       Filename
01920      * @return  string      new filename
01921      */
01922     protected function processJsFile($filename) {
01923         switch (TYPO3_MODE) {
01924             case 'FE':
01925                 $filename = t3lib_div::createVersionNumberedFilename($filename);
01926             break;
01927             case 'BE':
01928                 if ($this->compressJavascript) {
01929                     $filename = $this->getCompressor()->compressJsFile($filename);
01930                 }
01931             break;
01932         }
01933         return $filename;
01934     }
01935 
01936 }
01937 
01938 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_pagerenderer.php'])) {
01939     include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_pagerenderer.php']);
01940 }
01941 ?>