[TASK] Encapsulate bootstrap base code
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_pagerenderer.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2009-2011 Steffen Kamper <info@sk-typo3.de>
6 * (c) 2011 Kai Vogel <kai.vogel@speedprogs.de>
7 * All rights reserved
8 *
9 * This script is part of the TYPO3 project. The TYPO3 project is
10 * free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * The GNU General Public License can be found at
16 * http://www.gnu.org/copyleft/gpl.html.
17 * A copy is found in the textfile GPL.txt and important notices to the license
18 * from the author is found in LICENSE.txt distributed with these scripts.
19 *
20 *
21 * This script is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * This copyright notice MUST APPEAR in all copies of the script!
27 ***************************************************************/
28
29 /**
30 * TYPO3 pageRender class (new in TYPO3 4.3.0)
31 * This class render the HTML of a webpage, usable for BE and FE
32 *
33 * @author Steffen Kamper <info@sk-typo3.de>
34 * @author Kai Vogel <kai.vogel@speedprogs.de>
35 * @package TYPO3
36 * @subpackage t3lib
37 */
38 class t3lib_PageRenderer implements t3lib_Singleton {
39 // Constants for the part to be rendered
40 const PART_COMPLETE = 0;
41 const PART_HEADER = 1;
42 const PART_FOOTER = 2;
43
44 // Available adapters for extJs
45 const EXTJS_ADAPTER_JQUERY = 'jquery';
46 const EXTJS_ADAPTER_PROTOTYPE = 'prototype';
47 const EXTJS_ADAPTER_YUI = 'yui';
48
49 /**
50 * @var boolean
51 */
52 protected $compressJavascript = FALSE;
53
54 /**
55 * @var boolean
56 */
57 protected $compressCss = FALSE;
58
59 /**
60 * @var boolean
61 */
62 protected $removeLineBreaksFromTemplate = FALSE;
63
64 /**
65 * @var boolean
66 */
67 protected $concatenateFiles = FALSE;
68
69 /**
70 * @var boolean
71 */
72 protected $concatenateJavascript = FALSE;
73
74 /**
75 * @var boolean
76 */
77 protected $concatenateCss = FALSE;
78
79 /**
80 * @var boolean
81 */
82 protected $moveJsFromHeaderToFooter = FALSE;
83
84 /**
85 * @var t3lib_cs
86 */
87 protected $csConvObj;
88
89 /**
90 * @var t3lib_l10n_Locales
91 */
92 protected $locales;
93
94 /**
95 * The language key
96 * Two character string or 'default'
97 *
98 * @var string
99 */
100 protected $lang;
101
102 /**
103 * @var t3lib_Compressor
104 */
105 protected $compressor;
106
107 // Arrays containing associative array for the included files
108
109 /**
110 * @var array
111 */
112 protected $jsFiles = array();
113
114 /**
115 * @var array
116 */
117 protected $jsFooterFiles = array();
118
119 /**
120 * @var array
121 */
122 protected $jsLibs = array();
123
124 /**
125 * @var array
126 */
127 protected $jsFooterLibs = array();
128
129 /**
130 * @var array
131 */
132 protected $cssFiles = array();
133
134 /**
135 * The title of the page
136 *
137 * @var string
138 */
139 protected $title;
140
141 /**
142 * Charset for the rendering
143 *
144 * @var string
145 */
146 protected $charSet;
147
148 /**
149 * @var string
150 */
151 protected $favIcon;
152
153 /**
154 * @var string
155 */
156 protected $baseUrl;
157
158 /**
159 * @var boolean
160 */
161 protected $renderXhtml = TRUE;
162
163
164 // Static header blocks
165
166 /**
167 * @var string
168 */
169 protected $xmlPrologAndDocType = '';
170
171 /**
172 * @var array
173 */
174 protected $metaTags = array();
175
176 /**
177 * @var array
178 */
179 protected $inlineComments = array();
180
181 /**
182 * @var array
183 */
184 protected $headerData = array();
185
186 /**
187 * @var array
188 */
189 protected $footerData = array();
190
191 /**
192 * @var string
193 */
194 protected $titleTag = '<title>|</title>';
195
196 /**
197 * @var string
198 */
199 protected $metaCharsetTag = '<meta http-equiv="Content-Type" content="text/html; charset=|" />';
200
201 /**
202 * @var string
203 */
204 protected $htmlTag = '<html>';
205
206 /**
207 * @var string
208 */
209 protected $headTag = '<head>';
210
211 /**
212 * @var string
213 */
214 protected $baseUrlTag = '<base href="|" />';
215
216 /**
217 * @var string
218 */
219 protected $iconMimeType = '';
220
221 /**
222 * @var string
223 */
224 protected $shortcutTag = '<link rel="shortcut icon" href="%1$s"%2$s />
225 <link rel="icon" href="%1$s"%2$s />';
226
227 // Static inline code blocks
228
229 /**
230 * @var array
231 */
232 protected $jsInline = array();
233
234 /**
235 * @var array
236 */
237 protected $jsFooterInline = array();
238
239 /**
240 * @var array
241 */
242 protected $extOnReadyCode = array();
243
244 /**
245 * @var array
246 */
247 protected $cssInline = array();
248
249 /**
250 * @var string
251 */
252 protected $bodyContent;
253
254 /**
255 * @var string
256 */
257 protected $templateFile;
258
259 /**
260 * @var array
261 */
262 protected $jsLibraryNames = array('prototype', 'scriptaculous', 'extjs');
263
264 // Paths to contibuted libraries
265
266 /**
267 * @var string
268 */
269 protected $prototypePath = 'contrib/prototype/';
270
271 /**
272 * @var string
273 */
274 protected $scriptaculousPath = 'contrib/scriptaculous/';
275
276 /**
277 * @var string
278 */
279 protected $extCorePath = 'contrib/extjs/';
280
281 /**
282 * @var string
283 */
284 protected $extJsPath = 'contrib/extjs/';
285
286 /**
287 * @var string
288 */
289 protected $svgPath = 'contrib/websvg/';
290
291 // Internal flags for JS-libraries
292
293 /**
294 * @var boolean
295 */
296 protected $addPrototype = FALSE;
297
298 /**
299 * @var boolean
300 */
301 protected $addScriptaculous = FALSE;
302
303 /**
304 * @var array
305 */
306 protected $addScriptaculousModules = array('builder' => FALSE, 'effects' => FALSE, 'dragdrop' => FALSE, 'controls' => FALSE, 'slider' => FALSE);
307
308 /**
309 * @var boolean
310 */
311 protected $addExtJS = FALSE;
312
313 /**
314 * @var boolean
315 */
316 protected $addExtCore = FALSE;
317
318 /**
319 * @var string
320 */
321 protected $extJSadapter = 'ext/ext-base.js';
322
323 /**
324 * @var boolean
325 */
326 protected $extDirectCodeAdded = FALSE;
327
328 /**
329 * @var boolean
330 */
331 protected $enableExtJsDebug = FALSE;
332
333 /**
334 * @var boolean
335 */
336 protected $enableExtCoreDebug = FALSE;
337
338 /**
339 * @var boolean
340 */
341 protected $extJStheme = TRUE;
342
343 /**
344 * @var boolean
345 */
346 protected $extJScss = TRUE;
347
348 /**
349 * @var boolean
350 */
351 protected $enableExtJSQuickTips = FALSE;
352
353 /**
354 * @var array
355 */
356 protected $inlineLanguageLabels = array();
357
358 /**
359 * @var array
360 */
361 protected $inlineLanguageLabelFiles = array();
362
363 /**
364 * @var array
365 */
366 protected $inlineSettings = array();
367
368 /**
369 * @var array
370 */
371 protected $inlineJavascriptWrap = array();
372
373 /**
374 * Saves error messages generated during compression
375 *
376 * @var string
377 */
378 protected $compressError = '';
379
380 /**
381 * Is empty string for HTML and ' /' for XHTML rendering
382 *
383 * @var string
384 */
385 protected $endingSlash = '';
386
387 /**
388 * SVG library
389 *
390 * @var boolean
391 */
392 protected $addSvg = FALSE;
393
394 /**
395 * @var boolean
396 */
397 protected $enableSvgDebug = FALSE;
398
399 /**
400 * Used by BE modules
401 *
402 * @var null|string
403 */
404 public $backPath;
405
406 /**
407 * @param string $templateFile Declare the used template file. Omit this parameter will use default template
408 * @param string $backPath Relative path to typo3-folder. It varies for BE modules, in FE it will be typo3/
409 */
410 public function __construct($templateFile = '', $backPath = NULL) {
411
412 $this->reset();
413 $this->csConvObj = t3lib_div::makeInstance('t3lib_cs');
414 $this->locales = t3lib_div::makeInstance('t3lib_l10n_Locales');
415
416 if (strlen($templateFile)) {
417 $this->templateFile = $templateFile;
418 }
419 $this->backPath = isset($backPath) ? $backPath : $GLOBALS['BACK_PATH'];
420
421 $this->inlineJavascriptWrap = array(
422 '<script type="text/javascript">' . LF . '/*<![CDATA[*/' . LF . '<!-- ' . LF,
423 '// -->' . LF . '/*]]>*/' . LF . '</script>' . LF
424 );
425 $this->inlineCssWrap = array(
426 '<style type="text/css">' . LF . '/*<![CDATA[*/' . LF . '<!-- ' . LF,
427 '-->' . LF . '/*]]>*/' . LF . '</style>' . LF
428 );
429 }
430
431 /**
432 * Reset all vars to initial values
433 *
434 * @return void
435 */
436 protected function reset() {
437 $this->templateFile = TYPO3_mainDir . 'templates/template_page_backend.html';
438 $this->jsFiles = array();
439 $this->jsFooterFiles = array();
440 $this->jsInline = array();
441 $this->jsFooterInline = array();
442 $this->jsLibs = array();
443 $this->cssFiles = array();
444 $this->cssInline = array();
445 $this->metaTags = array();
446 $this->inlineComments = array();
447 $this->headerData = array();
448 $this->footerData = array();
449 $this->extOnReadyCode = array();
450 }
451
452 /*****************************************************/
453 /* */
454 /* Public Setters */
455 /* */
456 /* */
457 /*****************************************************/
458
459 /**
460 * Sets the title
461 *
462 * @param string $title title of webpage
463 * @return void
464 */
465 public function setTitle($title) {
466 $this->title = $title;
467 }
468
469 /**
470 * Enables/disables rendering of XHTML code
471 *
472 * @param boolean $enable Enable XHTML
473 * @return void
474 */
475 public function setRenderXhtml($enable) {
476 $this->renderXhtml = $enable;
477 }
478
479 /**
480 * Sets xml prolog and docType
481 *
482 * @param string $xmlPrologAndDocType Complete tags for xml prolog and docType
483 * @return void
484 */
485 public function setXmlPrologAndDocType($xmlPrologAndDocType) {
486 $this->xmlPrologAndDocType = $xmlPrologAndDocType;
487 }
488
489 /**
490 * Sets meta charset
491 *
492 * @param string $charSet Used charset
493 * @return void
494 */
495 public function setCharSet($charSet) {
496 $this->charSet = $charSet;
497 }
498
499 /**
500 * Sets language
501 *
502 * @param string $lang Used language
503 * @return void
504 */
505 public function setLanguage($lang) {
506 $this->lang = $lang;
507 }
508
509 /**
510 * Set the meta charset tag
511 *
512 * @param string $metaCharsetTag
513 * @return void
514 */
515 public function setMetaCharsetTag($metaCharsetTag) {
516 $this->metaCharsetTag = $metaCharsetTag;
517 }
518
519 /**
520 * Sets html tag
521 *
522 * @param string $htmlTag Html tag
523 * @return void
524 */
525 public function setHtmlTag($htmlTag) {
526 $this->htmlTag = $htmlTag;
527 }
528
529 /**
530 * Sets HTML head tag
531 *
532 * @param string $headTag HTML head tag
533 * @return void
534 */
535 public function setHeadTag($headTag) {
536 $this->headTag = $headTag;
537 }
538
539 /**
540 * Sets favicon
541 *
542 * @param string $favIcon
543 * @return void
544 */
545 public function setFavIcon($favIcon) {
546 $this->favIcon = $favIcon;
547 }
548
549 /**
550 * Sets icon mime type
551 *
552 * @param string $iconMimeType
553 * @return void
554 */
555 public function setIconMimeType($iconMimeType) {
556 $this->iconMimeType = $iconMimeType;
557 }
558
559 /**
560 * Sets HTML base URL
561 *
562 * @param string $baseUrl HTML base URL
563 * @return void
564 */
565 public function setBaseUrl($baseUrl) {
566 $this->baseUrl = $baseUrl;
567 }
568
569 /**
570 * Sets template file
571 *
572 * @param string $file
573 * @return void
574 */
575 public function setTemplateFile($file) {
576 $this->templateFile = $file;
577 }
578
579 /**
580 * Sets back path
581 *
582 * @param string $backPath
583 * @return void
584 */
585 public function setBackPath($backPath) {
586 $this->backPath = $backPath;
587 }
588
589 /**
590 * Sets Content for Body
591 *
592 * @param string $content
593 * @return void
594 */
595 public function setBodyContent($content) {
596 $this->bodyContent = $content;
597 }
598
599 /**
600 * Sets path to prototype library (relative to typo3 directory)
601 *
602 * @param string $path Path to prototype library
603 * @return void
604 */
605 public function setPrototypePath($path) {
606 $this->prototypePath = $path;
607 }
608
609 /**
610 * Sets Path for scriptaculous library (relative to typo3 directory)
611 *
612 * @param string $path
613 * @return void
614 */
615 public function setScriptaculousPath($path) {
616 $this->scriptaculousPath = $path;
617 }
618
619 /**
620 * Sets Path for Ext Core library (relative to typo3 directory)
621 *
622 * @param string $path
623 * @return void
624 */
625 public function setExtCorePath($path) {
626 $this->extCorePath = $path;
627 }
628
629 /**
630 * Sets Path for ExtJs library (relative to typo3 directory)
631 *
632 * @param string $path
633 * @return void
634 */
635 public function setExtJsPath($path) {
636 $this->extJsPath = $path;
637 }
638
639 /**
640 * Sets Path for SVG library (websvg)
641 *
642 * @param string $path
643 * @return void
644 */
645 public function setSvgPath($path) {
646 $this->svgPath = $path;
647 }
648
649 /*****************************************************/
650 /* */
651 /* Public Enablers / Disablers */
652 /* */
653 /* */
654 /*****************************************************/
655
656 /**
657 * Enables MoveJsFromHeaderToFooter
658 * @return void
659 */
660 public function enableMoveJsFromHeaderToFooter() {
661 $this->moveJsFromHeaderToFooter = TRUE;
662 }
663
664 /**
665 * Disables MoveJsFromHeaderToFooter
666 * @return void
667 */
668 public function disableMoveJsFromHeaderToFooter() {
669 $this->moveJsFromHeaderToFooter = FALSE;
670 }
671
672 /**
673 * Enables compression of javascript
674 * @return void
675 */
676 public function enableCompressJavascript() {
677 $this->compressJavascript = TRUE;
678 }
679
680 /**
681 * Disables compression of javascript
682 * @return void
683 */
684 public function disableCompressJavascript() {
685 $this->compressJavascript = FALSE;
686 }
687
688 /**
689 * Enables compression of css
690 * @return void
691 */
692 public function enableCompressCss() {
693 $this->compressCss = TRUE;
694 }
695
696 /**
697 * Disables compression of css
698 * @return void
699 */
700 public function disableCompressCss() {
701 $this->compressCss = FALSE;
702 }
703
704 /**
705 * Enables concatenation of js and css files
706 * @return void
707 */
708 public function enableConcatenateFiles() {
709 $this->concatenateFiles = TRUE;
710 }
711
712 /**
713 * Disables concatenation of js and css files
714 * @return void
715 */
716 public function disableConcatenateFiles() {
717 $this->concatenateFiles = FALSE;
718 }
719
720 /**
721 * Enables concatenation of js files
722 * @return void
723 */
724 public function enableConcatenateJavascript() {
725 $this->concatenateJavascript = TRUE;
726 }
727
728 /**
729 * Disables concatenation of js files
730 * @return void
731 */
732 public function disableConcatenateJavascript() {
733 $this->concatenateJavascript = FALSE;
734 }
735
736 /**
737 * Enables concatenation of css files
738 * @return void
739 */
740 public function enableConcatenateCss() {
741 $this->concatenateCss = TRUE;
742 }
743
744 /**
745 * Disables concatenation of css files
746 * @return void
747 */
748 public function disableConcatenateCss() {
749 $this->concatenateCss = FALSE;
750 }
751
752 /**
753 * Sets removal of all line breaks in template
754 * @return void
755 */
756 public function enableRemoveLineBreaksFromTemplate() {
757 $this->removeLineBreaksFromTemplate = TRUE;
758 }
759
760 /**
761 * Unsets removal of all line breaks in template
762 * @return void
763 */
764 public function disableRemoveLineBreaksFromTemplate() {
765 $this->removeLineBreaksFromTemplate = FALSE;
766 }
767
768 /**
769 * Enables Debug Mode
770 * This is a shortcut to switch off all compress/concatenate features to enable easier debug
771 * @return void
772 */
773 public function enableDebugMode() {
774 $this->compressJavascript = FALSE;
775 $this->compressCss = FALSE;
776 $this->concatenateFiles = FALSE;
777 $this->removeLineBreaksFromTemplate = FALSE;
778 $this->enableExtCoreDebug = TRUE;
779 $this->enableExtJsDebug = TRUE;
780 $this->enableSvgDebug = TRUE;
781 }
782
783 /*****************************************************/
784 /* */
785 /* Public Getters */
786 /* */
787 /* */
788 /*****************************************************/
789
790 /**
791 * Gets the title
792 *
793 * @return string $title Title of webpage
794 */
795 public function getTitle() {
796 return $this->title;
797 }
798
799 /**
800 * Gets the charSet
801 *
802 * @return string $charSet
803 */
804 public function getCharSet() {
805 return $this->charSet;
806 }
807
808 /**
809 * Gets the language
810 *
811 * @return string $lang
812 */
813 public function getLanguage() {
814 return $this->lang;
815 }
816
817 /**
818 * Returns rendering mode XHTML or HTML
819 *
820 * @return boolean TRUE if XHTML, FALSE if HTML
821 */
822 public function getRenderXhtml() {
823 return $this->renderXhtml;
824 }
825
826 /**
827 * Gets html tag
828 *
829 * @return string $htmlTag Html tag
830 */
831 public function getHtmlTag() {
832 return $this->htmlTag;
833 }
834
835 /**
836 * Get meta charset
837 *
838 * @return string
839 */
840 public function getMetaCharsetTag() {
841 return $this->metaCharsetTag;
842 }
843
844 /**
845 * Gets head tag
846 *
847 * @return string $tag Head tag
848 */
849 public function getHeadTag() {
850 return $this->headTag;
851 }
852
853 /**
854 * Gets favicon
855 *
856 * @return string $favIcon
857 */
858 public function getFavIcon() {
859 return $this->favIcon;
860 }
861
862 /**
863 * Gets icon mime type
864 *
865 * @return string $iconMimeType
866 */
867 public function getIconMimeType() {
868 return $this->iconMimeType;
869 }
870
871 /**
872 * Gets HTML base URL
873 *
874 * @return string $url
875 */
876 public function getBaseUrl() {
877 return $this->baseUrl;
878 }
879
880 /**
881 * Gets template file
882 *
883 * @return string
884 */
885 public function getTemplateFile() {
886 return $this->templateFile;
887 }
888
889 /**
890 * Gets MoveJsFromHeaderToFooter
891 *
892 * @return boolean
893 */
894 public function getMoveJsFromHeaderToFooter() {
895 return $this->moveJsFromHeaderToFooter;
896 }
897
898 /**
899 * Gets compress of javascript
900 *
901 * @return boolean
902 */
903 public function getCompressJavascript() {
904 return $this->compressJavascript;
905 }
906
907 /**
908 * Gets compress of css
909 *
910 * @return boolean
911 */
912 public function getCompressCss() {
913 return $this->compressCss;
914 }
915
916 /**
917 * Gets concatenate of js and css files
918 *
919 * @return boolean
920 */
921 public function getConcatenateFiles() {
922 return $this->concatenateFiles;
923 }
924
925 /**
926 * Gets concatenate of js files
927 *
928 * @return boolean
929 */
930 public function getConcatenateJavascript() {
931 return $this->concatenateJavascript;
932 }
933
934 /**
935 * Gets concatenate of css files
936 *
937 * @return boolean
938 */
939 public function getConcatenateCss() {
940 return $this->concatenateCss;
941 }
942
943 /**
944 * Gets remove of empty lines from template
945 *
946 * @return boolean
947 */
948 public function getRemoveLineBreaksFromTemplate() {
949 return $this->removeLineBreaksFromTemplate;
950 }
951
952 /**
953 * Gets content for body
954 *
955 * @return string
956 */
957 public function getBodyContent() {
958 return $this->bodyContent;
959 }
960
961 /**
962 * Gets Path for prototype library (relative to typo3 directory)
963 *
964 * @return string
965 */
966 public function getPrototypePath() {
967 return $this->prototypePath;
968 }
969
970 /**
971 * Gets Path for scriptaculous library (relative to typo3 directory)
972 *
973 * @return string
974 */
975 public function getScriptaculousPath() {
976 return $this->scriptaculousPath;
977 }
978
979 /**
980 * Gets Path for Ext Core library (relative to typo3 directory)
981 *
982 * @return string
983 */
984 public function getExtCorePath() {
985 return $this->extCorePath;
986 }
987
988 /**
989 * Gets Path for ExtJs library (relative to typo3 directory)
990 *
991 * @return string
992 */
993 public function getExtJsPath() {
994 return $this->extJsPath;
995 }
996
997 /**
998 * Gets Path for SVG library (relative to typo3 directory)
999 *
1000 * @return string
1001 */
1002 public function getSvgPath() {
1003 return $this->svgPath;
1004 }
1005
1006 /**
1007 * Gets the inline language labels.
1008 *
1009 * @return array The inline language labels
1010 */
1011 public function getInlineLanguageLabels() {
1012 return $this->inlineLanguageLabels;
1013 }
1014
1015 /**
1016 * Gets the inline language files
1017 *
1018 * @return array
1019 */
1020 public function getInlineLanguageLabelFiles() {
1021 return $this->inlineLanguageLabelFiles;
1022 }
1023
1024 /*****************************************************/
1025 /* */
1026 /* Public Functions to add Data */
1027 /* */
1028 /* */
1029 /*****************************************************/
1030
1031 /**
1032 * Adds meta data
1033 *
1034 * @param string $meta Meta data (complete metatag)
1035 * @return void
1036 */
1037 public function addMetaTag($meta) {
1038 if (!in_array($meta, $this->metaTags)) {
1039 $this->metaTags[] = $meta;
1040 }
1041 }
1042
1043 /**
1044 * Adds inline HTML comment
1045 *
1046 * @param string $comment
1047 * @return void
1048 */
1049 public function addInlineComment($comment) {
1050 if (!in_array($comment, $this->inlineComments)) {
1051 $this->inlineComments[] = $comment;
1052 }
1053 }
1054
1055 /**
1056 * Adds header data
1057 *
1058 * @param string $data Free header data for HTML header
1059 * @return void
1060 */
1061 public function addHeaderData($data) {
1062 if (!in_array($data, $this->headerData)) {
1063 $this->headerData[] = $data;
1064 }
1065 }
1066
1067 /**
1068 * Adds footer data
1069 *
1070 * @param string $data Free header data for HTML header
1071 * @return void
1072 */
1073 public function addFooterData($data) {
1074 if (!in_array($data, $this->footerData)) {
1075 $this->footerData[] = $data;
1076 }
1077 }
1078
1079 /**
1080 * Adds JS Library. JS Library block is rendered on top of the JS files.
1081 *
1082 * @param string $name Arbitrary identifier
1083 * @param string $file File name
1084 * @param string $type Content Type
1085 * @param boolean $compress Flag if library should be compressed
1086 * @param boolean $forceOnTop Flag if added library should be inserted at begin of this block
1087 * @param string $allWrap
1088 * @param boolean $excludeFromConcatenation
1089 * @return void
1090 */
1091 public function addJsLibrary($name, $file, $type = 'text/javascript', $compress = FALSE, $forceOnTop = FALSE, $allWrap = '', $excludeFromConcatenation = FALSE) {
1092 if (!$type) {
1093 $type = 'text/javascript';
1094 }
1095 if (!in_array(strtolower($name), $this->jsLibs)) {
1096 $this->jsLibs[strtolower($name)] = array(
1097 'file' => $file,
1098 'type' => $type,
1099 'section' => self::PART_HEADER,
1100 'compress' => $compress,
1101 'forceOnTop' => $forceOnTop,
1102 'allWrap' => $allWrap,
1103 'excludeFromConcatenation' => $excludeFromConcatenation,
1104 );
1105 }
1106 }
1107
1108 /**
1109 * Adds JS Library to Footer. JS Library block is rendered on top of the Footer JS files.
1110 *
1111 * @param string $name Arbitrary identifier
1112 * @param string $file File name
1113 * @param string $type Content Type
1114 * @param boolean $compress Flag if library should be compressed
1115 * @param boolean $forceOnTop Flag if added library should be inserted at begin of this block
1116 * @param string $allWrap
1117 * @param boolean $excludeFromConcatenation
1118 * @return void
1119 */
1120 public function addJsFooterLibrary($name, $file, $type = 'text/javascript', $compress = FALSE, $forceOnTop = FALSE, $allWrap = '', $excludeFromConcatenation = FALSE) {
1121 if (!$type) {
1122 $type = 'text/javascript';
1123 }
1124 if (!in_array(strtolower($name), $this->jsLibs)) {
1125 $this->jsLibs[strtolower($name)] = array(
1126 'file' => $file,
1127 'type' => $type,
1128 'section' => self::PART_FOOTER,
1129 'compress' => $compress,
1130 'forceOnTop' => $forceOnTop,
1131 'allWrap' => $allWrap,
1132 'excludeFromConcatenation' => $excludeFromConcatenation,
1133 );
1134 }
1135 }
1136
1137 /**
1138 * Adds JS file
1139 *
1140 * @param string $file File name
1141 * @param string $type Content Type
1142 * @param boolean $compress
1143 * @param boolean $forceOnTop
1144 * @param string $allWrap
1145 * @param boolean $excludeFromConcatenation
1146 * @return void
1147 */
1148 public function addJsFile($file, $type = 'text/javascript', $compress = TRUE, $forceOnTop = FALSE, $allWrap = '', $excludeFromConcatenation = FALSE) {
1149 if (!$type) {
1150 $type = 'text/javascript';
1151 }
1152 if (!isset($this->jsFiles[$file])) {
1153 if (strpos($file, 'ajax.php?') !== FALSE) {
1154 $compress = FALSE;
1155 }
1156 $this->jsFiles[$file] = array(
1157 'file' => $file,
1158 'type' => $type,
1159 'section' => self::PART_HEADER,
1160 'compress' => $compress,
1161 'forceOnTop' => $forceOnTop,
1162 'allWrap' => $allWrap,
1163 'excludeFromConcatenation' => $excludeFromConcatenation,
1164 );
1165 }
1166 }
1167
1168 /**
1169 * Adds JS file to footer
1170 *
1171 * @param string $file File name
1172 * @param string $type Content Type
1173 * @param boolean $compress
1174 * @param boolean $forceOnTop
1175 * @param string $allWrap
1176 * @param boolean $excludeFromConcatenation
1177 * @return void
1178 */
1179 public function addJsFooterFile($file, $type = 'text/javascript', $compress = TRUE, $forceOnTop = FALSE, $allWrap = '', $excludeFromConcatenation = FALSE) {
1180 if (!$type) {
1181 $type = 'text/javascript';
1182 }
1183 if (!isset($this->jsFiles[$file])) {
1184 if (strpos($file, 'ajax.php?') !== FALSE) {
1185 $compress = FALSE;
1186 }
1187 $this->jsFiles[$file] = array(
1188 'file' => $file,
1189 'type' => $type,
1190 'section' => self::PART_FOOTER,
1191 'compress' => $compress,
1192 'forceOnTop' => $forceOnTop,
1193 'allWrap' => $allWrap,
1194 'excludeFromConcatenation' => $excludeFromConcatenation,
1195 );
1196 }
1197 }
1198
1199 /**
1200 * Adds JS inline code
1201 *
1202 * @param string $name
1203 * @param string $block
1204 * @param boolean $compress
1205 * @param boolean $forceOnTop
1206 * @return void
1207 */
1208 public function addJsInlineCode($name, $block, $compress = TRUE, $forceOnTop = FALSE) {
1209 if (!isset($this->jsInline[$name]) && !empty($block)) {
1210 $this->jsInline[$name] = array(
1211 'code' => $block . LF,
1212 'section' => self::PART_HEADER,
1213 'compress' => $compress,
1214 'forceOnTop' => $forceOnTop
1215 );
1216 }
1217 }
1218
1219 /**
1220 * Adds JS inline code to footer
1221 *
1222 * @param string $name
1223 * @param string $block
1224 * @param boolean $compress
1225 * @param boolean $forceOnTop
1226 * @return void
1227 */
1228 public function addJsFooterInlineCode($name, $block, $compress = TRUE, $forceOnTop = FALSE) {
1229 if (!isset($this->jsInline[$name]) && !empty($block)) {
1230 $this->jsInline[$name] = array(
1231 'code' => $block . LF,
1232 'section' => self::PART_FOOTER,
1233 'compress' => $compress,
1234 'forceOnTop' => $forceOnTop
1235 );
1236 }
1237 }
1238
1239 /**
1240 * Adds Ext.onready code, which will be wrapped in Ext.onReady(function() {...});
1241 *
1242 * @param string $block Javascript code
1243 * @param boolean $forceOnTop Position of the javascript code (TRUE for putting it on top, default is FALSE = bottom)
1244 * @return void
1245 */
1246 public function addExtOnReadyCode($block, $forceOnTop = FALSE) {
1247 if (!in_array($block, $this->extOnReadyCode)) {
1248 if ($forceOnTop) {
1249 array_unshift($this->extOnReadyCode, $block);
1250 } else {
1251 $this->extOnReadyCode[] = $block;
1252 }
1253 }
1254 }
1255
1256 /**
1257 * Adds the ExtDirect code
1258 *
1259 * @param array $filterNamespaces Limit the output to defined namespaces. If empty, all namespaces are generated
1260 * @return void
1261 */
1262 public function addExtDirectCode(array $filterNamespaces = array()) {
1263 if ($this->extDirectCodeAdded) {
1264 return;
1265 }
1266 $this->extDirectCodeAdded = TRUE;
1267
1268 if (count($filterNamespaces) === 0) {
1269 $filterNamespaces = array('TYPO3');
1270 }
1271
1272 // For ExtDirect we need flash message support
1273 $this->addJsFile(t3lib_div::resolveBackPath($this->backPath . '../t3lib/js/extjs/ux/flashmessages.js'));
1274
1275 // Add language labels for ExtDirect
1276 if (TYPO3_MODE === 'FE') {
1277 $this->addInlineLanguageLabelArray(array(
1278 'extDirect_timeoutHeader' => $GLOBALS['TSFE']->sL('LLL:EXT:lang/locallang_misc.xml:extDirect_timeoutHeader'),
1279 'extDirect_timeoutMessage' => $GLOBALS['TSFE']->sL('LLL:EXT:lang/locallang_misc.xml:extDirect_timeoutMessage'),
1280 ));
1281 } else {
1282 $this->addInlineLanguageLabelArray(array(
1283 'extDirect_timeoutHeader' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_misc.xml:extDirect_timeoutHeader'),
1284 'extDirect_timeoutMessage' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_misc.xml:extDirect_timeoutMessage'),
1285 ));
1286 }
1287
1288 $token = $api = '';
1289 if (TYPO3_MODE === 'BE') {
1290 $formprotection = t3lib_formprotection_Factory::get();
1291 $token = $formprotection->generateToken('extDirect');
1292 }
1293
1294 /** @var $extDirect t3lib_extjs_ExtDirectApi */
1295 $extDirect = t3lib_div::makeInstance('t3lib_extjs_ExtDirectApi');
1296 $api = $extDirect->getApiPhp($filterNamespaces);
1297 if ($api) {
1298 $this->addJsInlineCode('TYPO3ExtDirectAPI', $api, FALSE);
1299 }
1300 // Note: we need to iterate thru the object, because the addProvider method
1301 // does this only with multiple arguments
1302 $this->addExtOnReadyCode('
1303 (function() {
1304 TYPO3.ExtDirectToken = "' . $token . '";
1305 for (var api in Ext.app.ExtDirectAPI) {
1306 var provider = Ext.Direct.addProvider(Ext.app.ExtDirectAPI[api]);
1307 provider.on("beforecall", function(provider, transaction, meta) {
1308 if (transaction.data) {
1309 transaction.data[transaction.data.length] = TYPO3.ExtDirectToken;
1310 } else {
1311 transaction.data = [TYPO3.ExtDirectToken];
1312 }
1313 });
1314
1315 provider.on("call", function(provider, transaction, meta) {
1316 if (transaction.isForm) {
1317 transaction.params.securityToken = TYPO3.ExtDirectToken;
1318 }
1319 });
1320 }
1321 })();
1322
1323 var extDirectDebug = function(message, header, group) {
1324 var TYPO3ViewportInstance = null;
1325
1326 if (top && top.TYPO3 && typeof top.TYPO3.Backend === "object") {
1327 TYPO3ViewportInstance = top.TYPO3.Backend;
1328 } else if (typeof TYPO3 === "object" && typeof TYPO3.Backend === "object") {
1329 TYPO3ViewportInstance = TYPO3.Backend;
1330 }
1331
1332 if (TYPO3ViewportInstance !== null) {
1333 TYPO3ViewportInstance.DebugConsole.addTab(message, header, group);
1334 } else if (typeof console === "object") {
1335 console.log(message);
1336 } else {
1337 document.write(message);
1338 }
1339 };
1340
1341 Ext.Direct.on("exception", function(event) {
1342 if (event.code === Ext.Direct.exceptions.TRANSPORT && !event.where) {
1343 TYPO3.Flashmessage.display(
1344 TYPO3.Severity.error,
1345 TYPO3.l10n.localize("extDirect_timeoutHeader"),
1346 TYPO3.l10n.localize("extDirect_timeoutMessage"),
1347 30
1348 );
1349 } else {
1350 var backtrace = "";
1351 if (event.code === "parse") {
1352 extDirectDebug(
1353 "<p>" + event.xhr.responseText + "<\/p>",
1354 event.type,
1355 "ExtDirect - Exception"
1356 );
1357 } else if (event.code === "router") {
1358 TYPO3.Flashmessage.display(
1359 TYPO3.Severity.error,
1360 event.code,
1361 event.message,
1362 30
1363 );
1364 } else if (event.where) {
1365 backtrace = "<p style=\"margin-top: 20px;\">" +
1366 "<strong>Backtrace:<\/strong><br \/>" +
1367 event.where.replace(/#/g, "<br \/>#") +
1368 "<\/p>";
1369 extDirectDebug(
1370 "<p>" + event.message + "<\/p>" + backtrace,
1371 event.method,
1372 "ExtDirect - Exception"
1373 );
1374 }
1375
1376
1377 }
1378 });
1379
1380 Ext.Direct.on("event", function(event, provider) {
1381 if (typeof event.debug !== "undefined" && event.debug !== "") {
1382 extDirectDebug(event.debug, event.method, "ExtDirect - Debug");
1383 }
1384 });
1385 ',
1386 TRUE
1387 );
1388 }
1389
1390 /**
1391 * Adds CSS file
1392 *
1393 * @param string $file
1394 * @param string $rel
1395 * @param string $media
1396 * @param string $title
1397 * @param boolean $compress
1398 * @param boolean $forceOnTop
1399 * @param string $allWrap
1400 * @param boolean $excludeFromConcatenation
1401 * @return void
1402 */
1403 public function addCssFile($file, $rel = 'stylesheet', $media = 'all', $title = '', $compress = TRUE, $forceOnTop = FALSE, $allWrap = '', $excludeFromConcatenation = FALSE) {
1404 if (!isset($this->cssFiles[$file])) {
1405 $this->cssFiles[$file] = array(
1406 'file' => $file,
1407 'rel' => $rel,
1408 'media' => $media,
1409 'title' => $title,
1410 'compress' => $compress,
1411 'forceOnTop' => $forceOnTop,
1412 'allWrap' => $allWrap,
1413 'excludeFromConcatenation' => $excludeFromConcatenation,
1414 );
1415 }
1416 }
1417
1418 /**
1419 * Adds CSS inline code
1420 *
1421 * @param string $name
1422 * @param string $block
1423 * @param boolean $compress
1424 * @param boolean $forceOnTop
1425 * @return void
1426 */
1427 public function addCssInlineBlock($name, $block, $compress = FALSE, $forceOnTop = FALSE) {
1428 if (!isset($this->cssInline[$name]) && !empty($block)) {
1429 $this->cssInline[$name] = array(
1430 'code' => $block,
1431 'compress' => $compress,
1432 'forceOnTop' => $forceOnTop
1433 );
1434 }
1435 }
1436
1437 /**
1438 * Call function if you need the prototype library
1439 *
1440 * @return void
1441 */
1442 public function loadPrototype() {
1443 $this->addPrototype = TRUE;
1444 }
1445
1446 /**
1447 * Call function if you need the Scriptaculous library
1448 *
1449 * @param string $modules Add modules you need. use "all" if you need complete modules
1450 * @return void
1451 */
1452 public function loadScriptaculous($modules = 'all') {
1453 // Scriptaculous require prototype, so load prototype too.
1454 $this->addPrototype = TRUE;
1455 $this->addScriptaculous = TRUE;
1456 if ($modules) {
1457 if ($modules == 'all') {
1458 foreach ($this->addScriptaculousModules as $key => $value) {
1459 $this->addScriptaculousModules[$key] = TRUE;
1460 }
1461 } else {
1462 $mods = t3lib_div::trimExplode(',', $modules);
1463 foreach ($mods as $mod) {
1464 if (isset($this->addScriptaculousModules[strtolower($mod)])) {
1465 $this->addScriptaculousModules[strtolower($mod)] = TRUE;
1466 }
1467 }
1468 }
1469 }
1470 }
1471
1472 /**
1473 * call this function if you need the extJS library
1474 *
1475 * @param boolean $css Flag, if set the ext-css will be loaded
1476 * @param boolean $theme Flag, if set the ext-theme "grey" will be loaded
1477 * @param string $adapter Choose alternative adapter, possible values: yui, prototype, jquery
1478 * @return void
1479 */
1480 public function loadExtJS($css = TRUE, $theme = TRUE, $adapter = '') {
1481 if ($adapter) {
1482 // Empty $adapter will always load the ext adapter
1483 switch (t3lib_div::strtolower(trim($adapter))) {
1484 case self::EXTJS_ADAPTER_YUI :
1485 $this->extJSadapter = 'yui/ext-yui-adapter.js';
1486 break;
1487 case self::EXTJS_ADAPTER_PROTOTYPE :
1488 $this->extJSadapter = 'prototype/ext-prototype-adapter.js';
1489 break;
1490 case self::EXTJS_ADAPTER_JQUERY :
1491 $this->extJSadapter = 'jquery/ext-jquery-adapter.js';
1492 break;
1493 }
1494 }
1495 $this->addExtJS = TRUE;
1496 $this->extJStheme = $theme;
1497 $this->extJScss = $css;
1498 }
1499
1500 /**
1501 * Enables ExtJs QuickTips
1502 * Need extJs loaded
1503 *
1504 * @return void
1505 */
1506 public function enableExtJSQuickTips() {
1507 $this->enableExtJSQuickTips = TRUE;
1508 }
1509
1510 /**
1511 * Call function if you need the ExtCore library
1512 *
1513 * @return void
1514 */
1515 public function loadExtCore() {
1516 $this->addExtCore = TRUE;
1517 }
1518
1519 /**
1520 * Call function if you need the SVG library
1521 *
1522 * @return void
1523 */
1524 public function loadSvg() {
1525 $this->addSvg = TRUE;
1526 }
1527
1528 /**
1529 * Call this function to load debug version of ExtJS. Use this for development only
1530 * @return void
1531 */
1532 public function enableSvgDebug() {
1533 $this->enableSvgDebug = TRUE;
1534 }
1535
1536 /**
1537 * Call this function to force flash usage with SVG library
1538 * @return void
1539 */
1540 public function svgForceFlash() {
1541 $this->addMetaTag('<meta name="svg.render.forceflash" content="true" />');
1542 }
1543
1544 /**
1545 * Call this function to load debug version of ExtJS. Use this for development only
1546 * @return void
1547 */
1548 public function enableExtJsDebug() {
1549 $this->enableExtJsDebug = TRUE;
1550 }
1551
1552 /**
1553 * Call this function to load debug version of ExtCore. Use this for development only
1554 * @return void
1555 */
1556 public function enableExtCoreDebug() {
1557 $this->enableExtCoreDebug = TRUE;
1558 }
1559
1560 /**
1561 * Adds Javascript Inline Label. This will occur in TYPO3.lang - object
1562 * The label can be used in scripts with TYPO3.lang.<key>
1563 * Need extJs loaded
1564 *
1565 * @param string $key
1566 * @param string $value
1567 * @return void
1568 */
1569 public function addInlineLanguageLabel($key, $value) {
1570 $this->inlineLanguageLabels[$key] = $value;
1571 }
1572
1573 /**
1574 * Adds Javascript Inline Label Array. This will occur in TYPO3.lang - object
1575 * The label can be used in scripts with TYPO3.lang.<key>
1576 * Array will be merged with existing array.
1577 * Need extJs loaded
1578 *
1579 * @param array $array
1580 * @return void
1581 */
1582 public function addInlineLanguageLabelArray(array $array) {
1583 $this->inlineLanguageLabels = array_merge($this->inlineLanguageLabels, $array);
1584 }
1585
1586 /**
1587 * Gets labels to be used in JavaScript fetched from a locallang file.
1588 *
1589 * @param string $fileRef 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.
1590 * @param string $selectionPrefix Prefix to select the correct labels (default: '')
1591 * @param string $stripFromSelectionName Sub-prefix to be removed from label names in the result (default: '')
1592 * @param integer $errorMode Error mode (when file could not be found): 0 - syslog entry, 1 - do nothing, 2 - throw an exception
1593 * @return void
1594 */
1595 public function addInlineLanguageLabelFile($fileRef, $selectionPrefix = '', $stripFromSelectionName = '', $errorMode = 0) {
1596 $index = md5($fileRef . $selectionPrefix . $stripFromSelectionName);
1597 if ($fileRef && !isset($this->inlineLanguageLabelFiles[$index])) {
1598 $this->inlineLanguageLabelFiles[$index] = array(
1599 'fileRef' => $fileRef,
1600 'selectionPrefix' => $selectionPrefix,
1601 'stripFromSelectionName' => $stripFromSelectionName,
1602 'errorMode' => $errorMode
1603 );
1604 }
1605 }
1606
1607
1608 /**
1609 * Adds Javascript Inline Setting. This will occur in TYPO3.settings - object
1610 * The label can be used in scripts with TYPO3.setting.<key>
1611 * Need extJs loaded
1612 *
1613 * @param string $namespace
1614 * @param string $key
1615 * @param string $value
1616 * @return void
1617 */
1618 public function addInlineSetting($namespace, $key, $value) {
1619 if ($namespace) {
1620 if (strpos($namespace, '.')) {
1621 $parts = explode('.', $namespace);
1622 $a = &$this->inlineSettings;
1623 foreach ($parts as $part) {
1624 $a = &$a[$part];
1625 }
1626 $a[$key] = $value;
1627 } else {
1628 $this->inlineSettings[$namespace][$key] = $value;
1629 }
1630 } else {
1631 $this->inlineSettings[$key] = $value;
1632 }
1633 }
1634
1635 /**
1636 * Adds Javascript Inline Setting. This will occur in TYPO3.settings - object
1637 * The label can be used in scripts with TYPO3.setting.<key>
1638 * Array will be merged with existing array.
1639 * Need extJs loaded
1640 *
1641 * @param string $namespace
1642 * @param array $array
1643 * @return void
1644 */
1645 public function addInlineSettingArray($namespace, array $array) {
1646 if ($namespace) {
1647 if (strpos($namespace, '.')) {
1648 $parts = explode('.', $namespace);
1649 $a = &$this->inlineSettings;
1650 foreach ($parts as $part) {
1651 $a = &$a[$part];
1652 }
1653 $a = array_merge((array) $a, $array);
1654 } else {
1655 $this->inlineSettings[$namespace] = array_merge((array) $this->inlineSettings[$namespace], $array);
1656 }
1657 } else {
1658 $this->inlineSettings = array_merge($this->inlineSettings, $array);
1659 }
1660 }
1661
1662 /**
1663 * Adds content to body content
1664 *
1665 * @param string $content
1666 * @return void
1667 */
1668 public function addBodyContent($content) {
1669 $this->bodyContent .= $content;
1670 }
1671
1672 /*****************************************************/
1673 /* */
1674 /* Render Functions */
1675 /* */
1676 /*****************************************************/
1677
1678 /**
1679 * Render the section (Header or Footer)
1680 *
1681 * @param integer $part Section which should be rendered: self::PART_COMPLETE, self::PART_HEADER or self::PART_FOOTER
1682 * @return string Content of rendered section
1683 */
1684 public function render($part = self::PART_COMPLETE) {
1685 $this->prepareRendering();
1686
1687 list(
1688 $jsLibs,
1689 $jsFiles,
1690 $jsFooterFiles,
1691 $cssFiles,
1692 $jsInline,
1693 $cssInline,
1694 $jsFooterInline,
1695 $jsFooterLibs
1696 ) = $this->renderJavaScriptAndCss();
1697
1698 $metaTags = implode(LF, $this->metaTags);
1699 $markerArray = $this->getPreparedMarkerArray($jsLibs, $jsFiles, $jsFooterFiles, $cssFiles, $jsInline, $cssInline, $jsFooterInline, $jsFooterLibs, $metaTags);
1700 $template = $this->getTemplateForPart($part);
1701 $this->reset();
1702
1703 return trim(t3lib_parsehtml::substituteMarkerArray($template, $markerArray, '###|###'));
1704 }
1705
1706 /**
1707 * Remove ending slashes from static header block
1708 * if the page is beeing rendered as html (not xhtml)
1709 * and define property $this->endingSlash for further use
1710 *
1711 * @return void
1712 */
1713 protected function prepareRendering() {
1714 if ($this->getRenderXhtml()) {
1715 $this->endingSlash = ' /';
1716 } else {
1717 $this->metaCharsetTag = str_replace(' />', '>', $this->metaCharsetTag);
1718 $this->baseUrlTag = str_replace(' />', '>', $this->baseUrlTag);
1719 $this->shortcutTag = str_replace(' />', '>', $this->shortcutTag);
1720
1721 $this->endingSlash = '';
1722 }
1723 }
1724
1725 /**
1726 * Renders all JavaScript and CSS
1727 *
1728 * @return array<string>
1729 */
1730 protected function renderJavaScriptAndCss() {
1731 $this->executePreRenderHook();
1732
1733 $mainJsLibs = $this->renderMainJavaScriptLibraries();
1734
1735 if ($this->concatenateFiles || $this->concatenateJavascript || $this->concatenateCss) {
1736 // Do the file concatenation
1737 $this->doConcatenate();
1738 }
1739 if ($this->compressCss || $this->compressJavascript) {
1740 // Do the file compression
1741 $this->doCompress();
1742 }
1743
1744 $this->executeRenderPostTransformHook();
1745
1746 $cssFiles = $this->renderCssFiles();
1747 $cssInline = $this->renderCssInline();
1748 list($jsLibs, $jsFooterLibs) = $this->renderAdditionalJavaScriptLibraries();
1749 list($jsFiles, $jsFooterFiles) = $this->renderJavaScriptFiles();
1750 list($jsInline, $jsFooterInline) = $this->renderInlineJavaScript();
1751
1752 $jsLibs = $mainJsLibs . $jsLibs;
1753
1754 if ($this->moveJsFromHeaderToFooter) {
1755 $jsFooterLibs = $jsLibs . LF . $jsFooterLibs;
1756 $jsLibs = '';
1757 $jsFooterFiles = $jsFiles . LF . $jsFooterFiles;
1758 $jsFiles = '';
1759 $jsFooterInline = $jsInline . LF . $jsFooterInline;
1760 $jsInline = '';
1761 }
1762
1763 $this->executePostRenderHook($jsLibs, $jsFiles, $jsFooterFiles, $cssFiles, $jsInline, $cssInline, $jsFooterInline, $jsFooterLibs);
1764
1765 return array($jsLibs, $jsFiles, $jsFooterFiles, $cssFiles, $jsInline, $cssInline, $jsFooterInline, $jsFooterLibs);
1766 }
1767
1768 /**
1769 * Fills the marker array with the given strings and trims each value
1770 *
1771 * @param $jsLibs string
1772 * @param $jsFiles string
1773 * @param $jsFooterFiles string
1774 * @param $cssFiles string
1775 * @param $jsInline string
1776 * @param $cssInline string
1777 * @param $jsFooterInline string
1778 * @param $jsFooterLibs string
1779 * @param $metaTags string
1780 * @return array Marker array
1781 */
1782 protected function getPreparedMarkerArray($jsLibs, $jsFiles, $jsFooterFiles, $cssFiles, $jsInline, $cssInline, $jsFooterInline, $jsFooterLibs, $metaTags) {
1783 $markerArray = array(
1784 'XMLPROLOG_DOCTYPE' => $this->xmlPrologAndDocType,
1785 'HTMLTAG' => $this->htmlTag,
1786 'HEADTAG' => $this->headTag,
1787 'METACHARSET' => $this->charSet ? str_replace('|', htmlspecialchars($this->charSet), $this->metaCharsetTag) : '',
1788 'INLINECOMMENT' => $this->inlineComments ? LF . LF . '<!-- ' . LF . implode(LF, $this->inlineComments) . '-->' . LF . LF : '',
1789 'BASEURL' => $this->baseUrl ? str_replace('|', $this->baseUrl, $this->baseUrlTag) : '',
1790 'SHORTCUT' => $this->favIcon ? sprintf($this->shortcutTag, htmlspecialchars($this->favIcon), $this->iconMimeType) : '',
1791 'CSS_INCLUDE' => $cssFiles,
1792 'CSS_INLINE' => $cssInline,
1793 'JS_INLINE' => $jsInline,
1794 'JS_INCLUDE' => $jsFiles,
1795 'JS_LIBS' => $jsLibs,
1796 'TITLE' => $this->title ? str_replace('|', htmlspecialchars($this->title), $this->titleTag) : '',
1797 'META' => $metaTags,
1798 'HEADERDATA' => $this->headerData ? implode(LF, $this->headerData) : '',
1799 'FOOTERDATA' => $this->footerData ? implode(LF, $this->footerData) : '',
1800 'JS_LIBS_FOOTER' => $jsFooterLibs,
1801 'JS_INCLUDE_FOOTER' => $jsFooterFiles,
1802 'JS_INLINE_FOOTER' => $jsFooterInline,
1803 'BODY' => $this->bodyContent,
1804 );
1805 $markerArray = array_map('trim', $markerArray);
1806
1807 return $markerArray;
1808 }
1809
1810 /**
1811 * Reads the template file and returns the requested part as string
1812 *
1813 * @param integer $part
1814 * @return string
1815 */
1816 protected function getTemplateForPart($part) {
1817 $templateFile = t3lib_div::getFileAbsFileName($this->templateFile, TRUE);
1818 $template = t3lib_div::getUrl($templateFile);
1819
1820 if ($this->removeLineBreaksFromTemplate) {
1821 $template = strtr($template, array(LF => '', CR => ''));
1822 }
1823 if ($part != self::PART_COMPLETE) {
1824 $templatePart = explode('###BODY###', $template);
1825 $template = $templatePart[$part - 1];
1826 }
1827
1828 return $template;
1829 }
1830
1831 /**
1832 * Helper function for render the main JavaScript libraries
1833 * currently: prototype, SVG, ExtJs
1834 *
1835 * @return string Content with JavaScript libraries
1836 */
1837 protected function renderMainJavaScriptLibraries() {
1838 $out = '';
1839
1840 if ($this->addSvg) {
1841 $out .= '<script src="' . $this->processJsFile($this->backPath . $this->svgPath . 'svg.js') .
1842 '" data-path="' . $this->backPath . $this->svgPath .
1843 '"' . ($this->enableSvgDebug ? ' data-debug="true"' : '') . '></script>';
1844 }
1845
1846 if ($this->addPrototype) {
1847 $out .= '<script src="' . $this->processJsFile($this->backPath . $this->prototypePath . 'prototype.js') .
1848 '" type="text/javascript"></script>' . LF;
1849 unset($this->jsFiles[$this->backPath . $this->prototypePath . 'prototype.js']);
1850 }
1851
1852 if ($this->addScriptaculous) {
1853 $mods = array();
1854 foreach ($this->addScriptaculousModules as $key => $value) {
1855 if ($this->addScriptaculousModules[$key]) {
1856 $mods[] = $key;
1857 }
1858 }
1859 // Resolve dependencies
1860 if (in_array('dragdrop', $mods) || in_array('controls', $mods)) {
1861 $mods = array_merge(array('effects'), $mods);
1862 }
1863
1864 if (count($mods)) {
1865 foreach ($mods as $module) {
1866 $out .= '<script src="' . $this->processJsFile($this->backPath .
1867 $this->scriptaculousPath . $module . '.js') . '" type="text/javascript"></script>' . LF;
1868 unset($this->jsFiles[$this->backPath . $this->scriptaculousPath . $module . '.js']);
1869 }
1870 }
1871 $out .= '<script src="' . $this->processJsFile($this->backPath . $this->scriptaculousPath .
1872 'scriptaculous.js') . '" type="text/javascript"></script>' . LF;
1873 unset($this->jsFiles[$this->backPath . $this->scriptaculousPath . 'scriptaculous.js']);
1874 }
1875
1876 // Include extCore, but only if ExtJS is not included
1877 if ($this->addExtCore && !$this->addExtJS) {
1878 $out .= '<script src="' . $this->processJsFile($this->backPath .
1879 $this->extCorePath . 'ext-core' . ($this->enableExtCoreDebug ? '-debug' : '') . '.js') .
1880 '" type="text/javascript"></script>' . LF;
1881 unset($this->jsFiles[$this->backPath . $this->extCorePath . 'ext-core' . ($this->enableExtCoreDebug ? '-debug' : '') . '.js']);
1882 }
1883
1884 // Include extJS
1885 if ($this->addExtJS) {
1886 // Use the base adapter all the time
1887 $out .= '<script src="' . $this->processJsFile($this->backPath . $this->extJsPath .
1888 'adapter/' . ($this->enableExtJsDebug ?
1889 str_replace('.js', '-debug.js', $this->extJSadapter) : $this->extJSadapter)) .
1890 '" type="text/javascript"></script>' . LF;
1891 $out .= '<script src="' . $this->processJsFile($this->backPath . $this->extJsPath .
1892 'ext-all' . ($this->enableExtJsDebug ? '-debug' : '') . '.js') .
1893 '" type="text/javascript"></script>' . LF;
1894
1895 // Add extJS localization
1896 // Load standard ISO mapping and modify for use with ExtJS
1897 $localeMap = $this->locales->getIsoMapping();
1898 $localeMap[''] = 'en';
1899 $localeMap['default'] = 'en';
1900 // Greek
1901 $localeMap['gr'] = 'el_GR';
1902 // Norwegian Bokmaal
1903 $localeMap['no'] = 'no_BO';
1904 // Swedish
1905 $localeMap['se'] = 'se_SV';
1906
1907
1908 $extJsLang = isset($localeMap[$this->lang]) ? $localeMap[$this->lang] : $this->lang;
1909 // TODO autoconvert file from UTF8 to current BE charset if necessary!!!!
1910 $extJsLocaleFile = $this->extJsPath . 'locale/ext-lang-' . $extJsLang . '.js';
1911 if (file_exists(PATH_typo3 . $extJsLocaleFile)) {
1912 $out .= '<script src="' . $this->processJsFile($this->backPath .
1913 $extJsLocaleFile) . '" type="text/javascript" charset="utf-8"></script>' . LF;
1914 }
1915
1916 // Remove extjs from JScodeLibArray
1917 unset(
1918 $this->jsFiles[$this->backPath . $this->extJsPath . 'ext-all.js'],
1919 $this->jsFiles[$this->backPath . $this->extJsPath . 'ext-all-debug.js']
1920 );
1921 }
1922
1923 if (count($this->inlineLanguageLabelFiles)) {
1924 foreach ($this->inlineLanguageLabelFiles as $languageLabelFile) {
1925 $this->includeLanguageFileForInline(
1926 $languageLabelFile['fileRef'],
1927 $languageLabelFile['selectionPrefix'],
1928 $languageLabelFile['stripFromSelectionName'],
1929 $languageLabelFile['$errorMode']
1930 );
1931 }
1932 }
1933 unset($this->inlineLanguageLabelFiles);
1934
1935 // Convert labels/settings back to UTF-8 since json_encode() only works with UTF-8:
1936 if ($this->getCharSet() !== 'utf-8') {
1937 if ($this->inlineLanguageLabels) {
1938 $this->csConvObj->convArray($this->inlineLanguageLabels, $this->getCharSet(), 'utf-8');
1939 }
1940 if ($this->inlineSettings) {
1941 $this->csConvObj->convArray($this->inlineSettings, $this->getCharSet(), 'utf-8');
1942 }
1943 }
1944
1945 $inlineSettings = $this->inlineLanguageLabels ? 'TYPO3.lang = ' . json_encode($this->inlineLanguageLabels) . ';' : '';
1946 $inlineSettings .= $this->inlineSettings ? 'TYPO3.settings = ' . json_encode($this->inlineSettings) . ';' : '';
1947
1948 if ($this->addExtCore || $this->addExtJS) {
1949 // Set clear.gif, move it on top, add handler code
1950 $code = '';
1951 if (count($this->extOnReadyCode)) {
1952 foreach ($this->extOnReadyCode as $block) {
1953 $code .= $block;
1954 }
1955 }
1956
1957 $out .= $this->inlineJavascriptWrap[0] . '
1958 Ext.ns("TYPO3");
1959 Ext.BLANK_IMAGE_URL = "' . htmlspecialchars(t3lib_div::locationHeaderUrl($this->backPath . 'gfx/clear.gif')) . '";' . LF .
1960 $inlineSettings .
1961 'Ext.onReady(function() {' .
1962 ($this->enableExtJSQuickTips ? 'Ext.QuickTips.init();' . LF : '') . $code .
1963 ' });' . $this->inlineJavascriptWrap[1];
1964 unset ($this->extOnReadyCode);
1965
1966 // Include TYPO3.l10n object
1967 if (TYPO3_MODE === 'BE') {
1968 $out .= '<script src="' . $this->processJsFile($this->backPath . 'sysext/lang/res/js/be/typo3lang.js') . '" type="text/javascript" charset="utf-8"></script>' . LF;
1969 }
1970
1971 if ($this->extJStheme) {
1972 if (isset($GLOBALS['TBE_STYLES']['extJS']['theme'])) {
1973 $this->addCssFile($this->backPath . $GLOBALS['TBE_STYLES']['extJS']['theme'], 'stylesheet', 'all', '', TRUE, TRUE);
1974 } else {
1975 $this->addCssFile($this->backPath . $this->extJsPath . 'resources/css/xtheme-blue.css', 'stylesheet', 'all', '', TRUE, TRUE);
1976 }
1977 }
1978 if ($this->extJScss) {
1979 if (isset($GLOBALS['TBE_STYLES']['extJS']['all'])) {
1980 $this->addCssFile($this->backPath . $GLOBALS['TBE_STYLES']['extJS']['all'], 'stylesheet', 'all', '', TRUE, TRUE);
1981 } else {
1982 $this->addCssFile($this->backPath . $this->extJsPath . 'resources/css/ext-all-notheme.css', 'stylesheet', 'all', '', TRUE, TRUE);
1983 }
1984 }
1985 } else {
1986 if ($inlineSettings) {
1987 $out .= $this->inlineJavascriptWrap[0] . $inlineSettings . $this->inlineJavascriptWrap[1];
1988 }
1989 }
1990
1991 return $out;
1992 }
1993
1994 /**
1995 * Render CSS files
1996 *
1997 * @return string
1998 */
1999 protected function renderCssFiles() {
2000 $cssFiles = '';
2001 if (count($this->cssFiles)) {
2002 foreach ($this->cssFiles as $file => $properties) {
2003 $file = t3lib_div::resolveBackPath($file);
2004 $file = t3lib_div::createVersionNumberedFilename($file);
2005 $tag = '<link rel="' . htmlspecialchars($properties['rel']) .
2006 '" type="text/css" href="' . htmlspecialchars($file) .
2007 '" media="' . htmlspecialchars($properties['media']) .
2008 '"' . ($properties['title'] ? ' title="' . htmlspecialchars($properties['title']) . '"' : '') . $this->endingSlash . '>';
2009 if ($properties['allWrap'] && strpos($properties['allWrap'], '|') !== FALSE) {
2010 $tag = str_replace('|', $tag, $properties['allWrap']);
2011 }
2012 if ($properties['forceOnTop']) {
2013 $cssFiles = $tag . LF . $cssFiles;
2014 } else {
2015 $cssFiles .= LF . $tag;
2016 }
2017 }
2018 }
2019
2020 return $cssFiles;
2021 }
2022
2023 /**
2024 * Render inline CSS
2025 *
2026 * @return string
2027 */
2028 protected function renderCssInline() {
2029 $cssInline = '';
2030 if (count($this->cssInline)) {
2031 foreach ($this->cssInline as $name => $properties) {
2032 if ($properties['forceOnTop']) {
2033 $cssInline = '/*' . htmlspecialchars($name) . '*/' . LF . $properties['code'] . LF . $cssInline;
2034 } else {
2035 $cssInline .= '/*' . htmlspecialchars($name) . '*/' . LF . $properties['code'] . LF;
2036 }
2037 }
2038 $cssInline = $this->inlineCssWrap[0] . $cssInline . $this->inlineCssWrap[1];
2039 }
2040
2041 return $cssInline;
2042 }
2043
2044 /**
2045 * Render JavaScipt libraries
2046 *
2047 * @return array<string> jsLibs and jsFooterLibs strings
2048 */
2049 protected function renderAdditionalJavaScriptLibraries() {
2050 $jsLibs = '';
2051 $jsFooterLibs = '';
2052 if (count($this->jsLibs)) {
2053 foreach ($this->jsLibs as $properties) {
2054 $properties['file'] = t3lib_div::resolveBackPath($properties['file']);
2055 $properties['file'] = t3lib_div::createVersionNumberedFilename($properties['file']);
2056 $tag = '<script src="' . htmlspecialchars($properties['file']) . '" type="' . htmlspecialchars($properties['type']) . '"></script>';
2057 if ($properties['allWrap'] && strpos($properties['allWrap'], '|') !== FALSE) {
2058 $tag = str_replace('|', $tag, $properties['allWrap']);
2059 }
2060 if ($properties['forceOnTop']) {
2061 if ($properties['section'] === self::PART_HEADER) {
2062 $jsLibs = $tag . LF . $jsLibs;
2063 } else {
2064 $jsFooterLibs = $tag . LF . $jsFooterLibs;
2065 }
2066 } else {
2067 if ($properties['section'] === self::PART_HEADER) {
2068 $jsLibs .= LF . $tag;
2069 } else {
2070 $jsFooterLibs .= LF . $tag;
2071 }
2072 }
2073 }
2074 }
2075 if ($this->moveJsFromHeaderToFooter) {
2076 $jsFooterLibs = $jsLibs . LF . $jsFooterLibs;
2077 $jsLibs = '';
2078 }
2079
2080 return array($jsLibs, $jsFooterLibs);
2081 }
2082
2083 /**
2084 * Render JavaScript files
2085 *
2086 * @return array<string> jsFiles and jsFooterFiles strings
2087 */
2088 protected function renderJavaScriptFiles() {
2089 $jsFiles = '';
2090 $jsFooterFiles = '';
2091 if (count($this->jsFiles)) {
2092 foreach ($this->jsFiles as $file => $properties) {
2093 $file = t3lib_div::resolveBackPath($file);
2094 $file = t3lib_div::createVersionNumberedFilename($file);
2095 $tag = '<script src="' . htmlspecialchars($file) . '" type="' . htmlspecialchars($properties['type']) . '"></script>';
2096 if ($properties['allWrap'] && strpos($properties['allWrap'], '|') !== FALSE) {
2097 $tag = str_replace('|', $tag, $properties['allWrap']);
2098 }
2099 if ($properties['forceOnTop']) {
2100 if ($properties['section'] === self::PART_HEADER) {
2101 $jsFiles = $tag . LF . $jsFiles;
2102 } else {
2103 $jsFooterFiles = $tag . LF . $jsFooterFiles;
2104 }
2105 } else {
2106 if ($properties['section'] === self::PART_HEADER) {
2107 $jsFiles .= LF . $tag;
2108 } else {
2109 $jsFooterFiles .= LF . $tag;
2110 }
2111 }
2112 }
2113 }
2114 if ($this->moveJsFromHeaderToFooter) {
2115 $jsFooterFiles = $jsFiles . LF . $jsFooterFiles;
2116 $jsFiles = '';
2117 }
2118
2119 return array($jsFiles, $jsFooterFiles);
2120 }
2121
2122 /**
2123 * Render inline JavaScript
2124 *
2125 * @return array<string> jsInline and jsFooterInline string
2126 */
2127 protected function renderInlineJavaScript() {
2128 $jsInline = '';
2129 $jsFooterInline = '';
2130 if (count($this->jsInline)) {
2131 foreach ($this->jsInline as $name => $properties) {
2132 if ($properties['forceOnTop']) {
2133 if ($properties['section'] === self::PART_HEADER) {
2134 $jsInline = '/*' . htmlspecialchars($name) . '*/' . LF . $properties['code'] . LF . $jsInline;
2135 } else {
2136 $jsFooterInline = '/*' . htmlspecialchars($name) . '*/' . LF . $properties['code'] . LF . $jsFooterInline;
2137 }
2138 } else {
2139 if ($properties['section'] === self::PART_HEADER) {
2140 $jsInline .= '/*' . htmlspecialchars($name) . '*/' . LF . $properties['code'] . LF;
2141 } else {
2142 $jsFooterInline .= '/*' . htmlspecialchars($name) . '*/' . LF . $properties['code'] . LF;
2143 }
2144 }
2145 }
2146 }
2147 if ($jsInline) {
2148 $jsInline = $this->inlineJavascriptWrap[0] . $jsInline . $this->inlineJavascriptWrap[1];
2149 }
2150
2151 if ($jsFooterInline) {
2152 $jsFooterInline = $this->inlineJavascriptWrap[0] . $jsFooterInline . $this->inlineJavascriptWrap[1];
2153 }
2154 if ($this->moveJsFromHeaderToFooter) {
2155 $jsFooterInline = $jsInline . LF . $jsFooterInline;
2156 $jsInline = '';
2157 }
2158
2159 return array($jsInline, $jsFooterInline);
2160 }
2161
2162 /**
2163 * Include language file for inline usage
2164 *
2165 * @param string $fileRef
2166 * @param string $selectionPrefix
2167 * @param string $stripFromSelectionName
2168 * @param integer $errorMode
2169 * @return void
2170 * @throws RuntimeException
2171 */
2172 protected function includeLanguageFileForInline($fileRef, $selectionPrefix = '', $stripFromSelectionName = '', $errorMode = 0) {
2173 if (!isset($this->lang) || !isset($this->charSet)) {
2174 throw new RuntimeException('Language and character encoding are not set.', 1284906026);
2175 }
2176
2177 $labelsFromFile = array();
2178 $allLabels = t3lib_div::readLLfile($fileRef, $this->lang, $this->charSet, $errorMode);
2179
2180 // Regular expression to strip the selection prefix and possibly something from the label name:
2181 $labelPattern = '#^' . preg_quote($selectionPrefix, '#') . '(' . preg_quote($stripFromSelectionName, '#') . ')?#';
2182
2183 if ($allLabels !== FALSE) {
2184 // Merge language specific translations:
2185 if ($this->lang !== 'default' && isset($allLabels[$this->lang])) {
2186 $labels = array_merge($allLabels['default'], $allLabels[$this->lang]);
2187 } else {
2188 $labels = $allLabels['default'];
2189 }
2190
2191 // Iterate through all locallang labels:
2192 foreach ($labels as $label => $value) {
2193 if ($selectionPrefix === '') {
2194 $labelsFromFile[$label] = $value;
2195 } elseif (strpos($label, $selectionPrefix) === 0) {
2196 $key = preg_replace($labelPattern, '', $label);
2197 $labelsFromFile[$label] = $value;
2198 }
2199 }
2200
2201 $this->inlineLanguageLabels = array_merge($this->inlineLanguageLabels, $labelsFromFile);
2202 }
2203 }
2204
2205 /*****************************************************/
2206 /* */
2207 /* Tools */
2208 /* */
2209 /*****************************************************/
2210
2211 /**
2212 * Concatenate files into one file
2213 * registered handler
2214 *
2215 * @return void
2216 */
2217 protected function doConcatenate() {
2218 $this->doConcatenateCss();
2219 $this->doConcatenateJavaScript();
2220 }
2221
2222 /**
2223 * Concatenate JavaScript files according to the configuration.
2224 *
2225 * @return void
2226 */
2227 protected function doConcatenateJavaScript() {
2228 if ($this->concatenateFiles || $this->concatenateJavascript) {
2229 if (!empty($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['jsConcatenateHandler'])) {
2230 // use external concatenation routine
2231 $params = array(
2232 'jsLibs' => &$this->jsLibs,
2233 'jsFiles' => &$this->jsFiles,
2234 'jsFooterFiles' => &$this->jsFooterFiles,
2235 'headerData' => &$this->headerData,
2236 'footerData' => &$this->footerData,
2237 );
2238 t3lib_div::callUserFunction($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['jsConcatenateHandler'], $params, $this);
2239 } else {
2240 $this->jsLibs = $this->getCompressor()->concatenateJsFiles($this->jsLibs);
2241 $this->jsFiles = $this->getCompressor()->concatenateJsFiles($this->jsFiles);
2242 $this->jsFooterFiles = $this->getCompressor()->concatenateJsFiles($this->jsFooterFiles);
2243 }
2244 }
2245 }
2246
2247 /**
2248 * Concatenate CSS files according to configuration.
2249 *
2250 * @return void
2251 */
2252 protected function doConcatenateCss() {
2253 if ($this->concatenateFiles || $this->concatenateCss) {
2254 if (!empty($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['cssConcatenateHandler'])) {
2255 // use external concatenation routine
2256 $params = array(
2257 'cssFiles' => &$this->cssFiles,
2258 'headerData' => &$this->headerData,
2259 'footerData' => &$this->footerData,
2260 );
2261 t3lib_div::callUserFunction($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['cssConcatenateHandler'], $params, $this);
2262 } else {
2263 $cssOptions = array();
2264 if (TYPO3_MODE === 'BE') {
2265 $cssOptions = array('baseDirectories' => $GLOBALS['TBE_TEMPLATE']->getSkinStylesheetDirectories());
2266 }
2267 $this->cssFiles = $this->getCompressor()->concatenateCssFiles($this->cssFiles, $cssOptions);
2268 }
2269 }
2270 }
2271
2272 /**
2273 * Compresses inline code
2274 *
2275 * @return void
2276 */
2277 protected function doCompress() {
2278 $this->doCompressJavaScript();
2279 $this->doCompressCss();
2280 }
2281
2282 /**
2283 * Compresses CSS according to configuration.
2284 *
2285 * @return void
2286 */
2287 protected function doCompressCss() {
2288 if ($this->compressCss) {
2289 // Use external compression routine
2290 $params = array(
2291 'cssInline' => &$this->cssInline,
2292 'cssFiles' => &$this->cssFiles,
2293 'headerData' => &$this->headerData,
2294 'footerData' => &$this->footerData,
2295 );
2296
2297 if (!empty($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['cssCompressHandler'])) {
2298 // use external concatenation routine
2299 t3lib_div::callUserFunction($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['cssCompressHandler'], $params, $this);
2300 } else {
2301 $this->cssFiles = $this->getCompressor()->compressCssFiles($this->cssFiles);
2302 }
2303 }
2304 }
2305
2306 /**
2307 * Compresses JavaScript according to configuration.
2308 *
2309 * @return void
2310 */
2311 protected function doCompressJavaScript() {
2312 if ($this->compressJavascript) {
2313 if (!empty($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['jsCompressHandler'])) {
2314 // Use external compression routine
2315 $params = array(
2316 'jsInline' => &$this->jsInline,
2317 'jsFooterInline' => &$this->jsFooterInline,
2318 'jsLibs' => &$this->jsLibs,
2319 'jsFiles' => &$this->jsFiles,
2320 'jsFooterFiles' => &$this->jsFooterFiles,
2321 'headerData' => &$this->headerData,
2322 'footerData' => &$this->footerData,
2323 );
2324 t3lib_div::callUserFunction($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['jsCompressHandler'], $params, $this);
2325 } else {
2326 // Traverse the arrays, compress files
2327 if (count($this->jsInline)) {
2328 foreach ($this->jsInline as $name => $properties) {
2329 if ($properties['compress']) {
2330 $error = '';
2331 $this->jsInline[$name]['code'] = t3lib_div::minifyJavaScript($properties['code'], $error);
2332 if ($error) {
2333 $this->compressError .= 'Error with minify JS Inline Block "' . $name . '": ' . $error . LF;
2334 }
2335 }
2336 }
2337 }
2338 $this->jsLibs = $this->getCompressor()->compressJsFiles($this->jsLibs);
2339 $this->jsFiles = $this->getCompressor()->compressJsFiles($this->jsFiles);
2340 $this->jsFooterFiles = $this->getCompressor()->compressJsFiles($this->jsFooterFiles);
2341 }
2342 }
2343 }
2344
2345 /**
2346 * Returns instance of t3lib_Compressor
2347 *
2348 * @return t3lib_Compressor Instance of t3lib_Compressor
2349 */
2350 protected function getCompressor() {
2351 if ($this->compressor === NULL) {
2352 $this->compressor = t3lib_div::makeInstance('t3lib_Compressor');
2353 }
2354 return $this->compressor;
2355 }
2356
2357 /**
2358 * Processes a Javascript file dependent on the current context
2359 *
2360 * Adds the version number for Frontend, compresses the file for Backend
2361 *
2362 * @param string $filename Filename
2363 * @return string New filename
2364 */
2365 protected function processJsFile($filename) {
2366 switch (TYPO3_MODE) {
2367 case 'FE':
2368 if ($this->compressJavascript) {
2369 $filename = $this->getCompressor()->compressJsFile($filename);
2370 } else {
2371 $filename = t3lib_div::createVersionNumberedFilename($filename);
2372 }
2373 break;
2374 case 'BE':
2375 if ($this->compressJavascript) {
2376 $filename = $this->getCompressor()->compressJsFile($filename);
2377 }
2378 break;
2379 }
2380 return $filename;
2381 }
2382
2383 /*****************************************************/
2384 /* */
2385 /* Hooks */
2386 /* */
2387 /*****************************************************/
2388
2389 /**
2390 * Execute PreRenderHook for possible manuipulation
2391 *
2392 * @return void
2393 */
2394 protected function executePreRenderHook() {
2395 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_pagerenderer.php']['render-preProcess'])) {
2396 $params = array(
2397 'jsLibs' => &$this->jsLibs,
2398 'jsFooterLibs' => &$this->jsFooterLibs,
2399 'jsFiles' => &$this->jsFiles,
2400 'jsFooterFiles' => &$this->jsFooterFiles,
2401 'cssFiles' => &$this->cssFiles,
2402 'headerData' => &$this->headerData,
2403 'footerData' => &$this->footerData,
2404 'jsInline' => &$this->jsInline,
2405 'jsFooterInline' => &$this->jsFooterInline,
2406 'cssInline' => &$this->cssInline,
2407 );
2408 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_pagerenderer.php']['render-preProcess'] as $hook) {
2409 t3lib_div::callUserFunction($hook, $params, $this);
2410 }
2411 }
2412 }
2413
2414 /**
2415 * PostTransform for possible manuipulation of concatenated and compressed files
2416 *
2417 * @return void
2418 */
2419 protected function executeRenderPostTransformHook() {
2420 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_pagerenderer.php']['render-postTransform'])) {
2421 $params = array('jsLibs' => &$this->jsLibs,
2422 'jsFooterLibs' => &$this->jsFooterLibs,
2423 'jsFiles' => &$this->jsFiles,
2424 'jsFooterFiles' => &$this->jsFooterFiles,
2425 'cssFiles' => &$this->cssFiles,
2426 'headerData' => &$this->headerData,
2427 'footerData' => &$this->footerData,
2428 'jsInline' => &$this->jsInline,
2429 'jsFooterInline' => &$this->jsFooterInline,
2430 'cssInline' => &$this->cssInline,
2431 );
2432 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_pagerenderer.php']['render-postTransform'] as $hook) {
2433 t3lib_div::callUserFunction($hook, $params, $this);
2434 }
2435 }
2436 }
2437
2438 /**
2439 * Execute postRenderHook for possible manipulation
2440 *
2441 * @param $jsLibs string
2442 * @param $jsFiles string
2443 * @param $jsFooterFiles string
2444 * @param $cssFiles string
2445 * @param $jsInline string
2446 * @param $cssInline string
2447 * @param $jsFooterInline string
2448 * @param $jsFooterLibs string
2449 *
2450 * @return void
2451 */
2452 protected function executePostRenderHook(&$jsLibs, &$jsFiles, &$jsFooterFiles, &$cssFiles, &$jsInline, &$cssInline, &$jsFooterInline, &$jsFooterLibs) {
2453 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_pagerenderer.php']['render-postProcess'])) {
2454 $params = array(
2455 'jsLibs' => &$jsLibs,
2456 'jsFiles' => &$jsFiles,
2457 'jsFooterFiles' => &$jsFooterFiles,
2458 'cssFiles' => &$cssFiles,
2459 'headerData' => &$this->headerData,
2460 'footerData' => &$this->footerData,
2461 'jsInline' => &$jsInline,
2462 'cssInline' => &$cssInline,
2463 'xmlPrologAndDocType' => &$this->xmlPrologAndDocType,
2464 'htmlTag' => &$this->htmlTag,
2465 'headTag' => &$this->headTag,
2466 'charSet' => &$this->charSet,
2467 'metaCharsetTag' => &$this->metaCharsetTag,
2468 'shortcutTag' => &$this->shortcutTag,
2469 'inlineComments' => &$this->inlineComments,
2470 'baseUrl' => &$this->baseUrl,
2471 'baseUrlTag' => &$this->baseUrlTag,
2472 'favIcon' => &$this->favIcon,
2473 'iconMimeType' => &$this->iconMimeType,
2474 'titleTag' => &$this->titleTag,
2475 'title' => &$this->title,
2476 'metaTags' => &$this->metaTags,
2477 'jsFooterInline' => &$jsFooterInline,
2478 'jsFooterLibs' => &$jsFooterLibs,
2479 'bodyContent' => &$this->bodyContent
2480 );
2481 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_pagerenderer.php']['render-postProcess'] as $hook) {
2482 t3lib_div::callUserFunction($hook, $params, $this);
2483 }
2484 }
2485 }
2486 }
2487
2488 ?>