|
TYPO3 API
SVNRelease
|
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 ?>
1.8.0