TYPO3 CMS  TYPO3_6-2
PageRenderer.php
Go to the documentation of this file.
1 <?php
3 
19 
28 
29  // Constants for the part to be rendered
30  const PART_COMPLETE = 0;
31  const PART_HEADER = 1;
32  const PART_FOOTER = 2;
33  // Available adapters for extJs
34  const EXTJS_ADAPTER_JQUERY = 'jquery';
35  const EXTJS_ADAPTER_PROTOTYPE = 'prototype';
36  const EXTJS_ADAPTER_YUI = 'yui';
37  // jQuery Core version that is shipped with TYPO3
38  const JQUERY_VERSION_LATEST = '1.11.0';
39  // jQuery namespace options
40  const JQUERY_NAMESPACE_NONE = 'none';
41  const JQUERY_NAMESPACE_DEFAULT = 'jQuery';
42  const JQUERY_NAMESPACE_DEFAULT_NOCONFLICT = 'defaultNoConflict';
46  protected $compressJavascript = FALSE;
47 
51  protected $compressCss = FALSE;
52 
56  protected $removeLineBreaksFromTemplate = FALSE;
57 
61  protected $concatenateFiles = FALSE;
62 
66  protected $concatenateJavascript = FALSE;
67 
71  protected $concatenateCss = FALSE;
72 
76  protected $moveJsFromHeaderToFooter = FALSE;
77 
81  protected $csConvObj;
82 
86  protected $locales;
87 
94  protected $lang;
95 
102  protected $languageDependencies = array();
103 
107  protected $compressor;
108 
109  // Arrays containing associative array for the included files
113  protected $jsFiles = array();
114 
118  protected $jsFooterFiles = array();
119 
123  protected $jsLibs = array();
124 
128  protected $jsFooterLibs = array();
129 
133  protected $cssFiles = array();
134 
138  protected $cssLibs = array();
139 
145  protected $title;
146 
152  protected $charSet;
153 
157  protected $favIcon;
158 
162  protected $baseUrl;
163 
167  protected $renderXhtml = TRUE;
168 
169  // Static header blocks
173  protected $xmlPrologAndDocType = '';
174 
178  protected $metaTags = array();
179 
183  protected $inlineComments = array();
184 
188  protected $headerData = array();
189 
193  protected $footerData = array();
194 
198  protected $titleTag = '<title>|</title>';
199 
203  protected $metaCharsetTag = '<meta http-equiv="Content-Type" content="text/html; charset=|" />';
204 
208  protected $htmlTag = '<html>';
209 
213  protected $headTag = '<head>';
214 
218  protected $baseUrlTag = '<base href="|" />';
219 
223  protected $iconMimeType = '';
224 
228  protected $shortcutTag = '<link rel="shortcut icon" href="%1$s"%2$s />
229 <link rel="icon" href="%1$s"%2$s />';
230 
231  // Static inline code blocks
235  protected $jsInline = array();
236 
240  protected $jsFooterInline = array();
241 
245  protected $extOnReadyCode = array();
246 
250  protected $cssInline = array();
251 
255  protected $bodyContent;
256 
260  protected $templateFile;
261 
265  protected $jsLibraryNames = array('prototype', 'scriptaculous', 'extjs');
266 
267  // Paths to contibuted libraries
268 
273  protected $requireJsPath = 'contrib/requirejs/';
274 
278  protected $prototypePath = 'contrib/prototype/';
279 
283  protected $scriptaculousPath = 'contrib/scriptaculous/';
284 
288  protected $extCorePath = 'contrib/extjs/';
289 
293  protected $extJsPath = 'contrib/extjs/';
294 
298  protected $svgPath = 'contrib/websvg/';
299 
305  protected $jQueryPath = 'contrib/jquery/';
306 
307  // Internal flags for JS-libraries
325  protected $jQueryVersions = array();
326 
332  protected $availableLocalJqueryVersions = array(
333  '1.8.2', // jquery version shipped with TYPO3 6.0, still available in the contrib/ directory
334  '1.9.1',
335  self::JQUERY_VERSION_LATEST
336  );
337 
343  protected $jQueryCdnUrls = array(
344  'google' => '//ajax.googleapis.com/ajax/libs/jquery/%1$s/jquery%2$s.js',
345  'msn' => '//ajax.aspnetcdn.com/ajax/jQuery/jquery-%1$s%2$s.js',
346  'jquery' => 'http://code.jquery.com/jquery-%1$s%2$s.js'
347  );
348 
353  protected $addRequireJs = FALSE;
354 
359  protected $requireJsConfig = array();
360 
364  protected $addPrototype = FALSE;
365 
369  protected $addScriptaculous = FALSE;
370 
374  protected $addScriptaculousModules = array('builder' => FALSE, 'effects' => FALSE, 'dragdrop' => FALSE, 'controls' => FALSE, 'slider' => FALSE);
375 
379  protected $addExtJS = FALSE;
380 
384  protected $addExtCore = FALSE;
385 
389  protected $extJSadapter = 'ext/ext-base.js';
390 
394  protected $extDirectCodeAdded = FALSE;
395 
399  protected $enableExtJsDebug = FALSE;
400 
404  protected $enableExtCoreDebug = FALSE;
405 
409  protected $enableJqueryDebug = FALSE;
410 
414  protected $extJStheme = TRUE;
415 
419  protected $extJScss = TRUE;
420 
424  protected $enableExtJSQuickTips = FALSE;
425 
429  protected $inlineLanguageLabels = array();
430 
434  protected $inlineLanguageLabelFiles = array();
435 
439  protected $inlineSettings = array();
440 
444  protected $inlineJavascriptWrap = array();
445 
451  protected $compressError = '';
452 
458  protected $endingSlash = '';
459 
465  protected $addSvg = FALSE;
466 
470  protected $enableSvgDebug = FALSE;
471 
477  public $backPath;
478 
483  public function __construct($templateFile = '', $backPath = NULL) {
484  $this->reset();
485  $this->csConvObj = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Charset\\CharsetConverter');
486  $this->locales = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Localization\\Locales');
487  if (strlen($templateFile)) {
488  $this->templateFile = $templateFile;
489  }
490  $this->backPath = isset($backPath) ? $backPath : $GLOBALS['BACK_PATH'];
491  $this->inlineJavascriptWrap = array(
492  '<script type="text/javascript">' . LF . '/*<![CDATA[*/' . LF,
493  '/*]]>*/' . LF . '</script>' . LF
494  );
495  $this->inlineCssWrap = array(
496  '<style type="text/css">' . LF . '/*<![CDATA[*/' . LF . '<!-- ' . LF,
497  '-->' . LF . '/*]]>*/' . LF . '</style>' . LF
498  );
499  }
500 
506  protected function reset() {
507  $this->templateFile = 'EXT:core/Resources/Private/Templates/PageRenderer.html';
508  $this->jsFiles = array();
509  $this->jsFooterFiles = array();
510  $this->jsInline = array();
511  $this->jsFooterInline = array();
512  $this->jsLibs = array();
513  $this->cssFiles = array();
514  $this->cssInline = array();
515  $this->metaTags = array();
516  $this->inlineComments = array();
517  $this->headerData = array();
518  $this->footerData = array();
519  $this->extOnReadyCode = array();
520  $this->jQueryVersions = array();
521  }
522 
523  /*****************************************************/
524  /* */
525  /* Public Setters */
526  /* */
527  /* */
528  /*****************************************************/
535  public function setTitle($title) {
536  $this->title = $title;
537  }
538 
545  public function setRenderXhtml($enable) {
546  $this->renderXhtml = $enable;
547  }
548 
556  $this->xmlPrologAndDocType = $xmlPrologAndDocType;
557  }
558 
565  public function setCharSet($charSet) {
566  $this->charSet = $charSet;
567  }
568 
575  public function setLanguage($lang) {
576  $this->lang = $lang;
577  $this->languageDependencies = array();
578 
579  // Language is found. Configure it:
580  if (in_array($this->lang, $this->locales->getLocales())) {
581  $this->languageDependencies[] = $this->lang;
582  foreach ($this->locales->getLocaleDependencies($this->lang) as $language) {
583  $this->languageDependencies[] = $language;
584  }
585  }
586  }
587 
595  $this->metaCharsetTag = $metaCharsetTag;
596  }
597 
604  public function setHtmlTag($htmlTag) {
605  $this->htmlTag = $htmlTag;
606  }
607 
614  public function setHeadTag($headTag) {
615  $this->headTag = $headTag;
616  }
617 
624  public function setFavIcon($favIcon) {
625  $this->favIcon = $favIcon;
626  }
627 
634  public function setIconMimeType($iconMimeType) {
635  $this->iconMimeType = $iconMimeType;
636  }
637 
644  public function setBaseUrl($baseUrl) {
645  $this->baseUrl = $baseUrl;
646  }
647 
654  public function setTemplateFile($file) {
655  $this->templateFile = $file;
656  }
657 
664  public function setBackPath($backPath) {
665  $this->backPath = $backPath;
666  }
667 
674  public function setBodyContent($content) {
675  $this->bodyContent = $content;
676  }
677 
684  public function setRequireJsPath($path) {
685  $this->requireJsPath = $path;
686  }
687 
694  public function setPrototypePath($path) {
695  $this->prototypePath = $path;
696  }
697 
704  public function setScriptaculousPath($path) {
705  $this->scriptaculousPath = $path;
706  }
707 
714  public function setExtCorePath($path) {
715  $this->extCorePath = $path;
716  }
717 
724  public function setExtJsPath($path) {
725  $this->extJsPath = $path;
726  }
727 
734  public function setSvgPath($path) {
735  $this->svgPath = $path;
736  }
737 
738  /*****************************************************/
739  /* */
740  /* Public Enablers / Disablers */
741  /* */
742  /* */
743  /*****************************************************/
749  public function enableMoveJsFromHeaderToFooter() {
750  $this->moveJsFromHeaderToFooter = TRUE;
751  }
752 
759  $this->moveJsFromHeaderToFooter = FALSE;
760  }
761 
767  public function enableCompressJavascript() {
768  $this->compressJavascript = TRUE;
769  }
770 
776  public function disableCompressJavascript() {
777  $this->compressJavascript = FALSE;
778  }
779 
785  public function enableCompressCss() {
786  $this->compressCss = TRUE;
787  }
788 
794  public function disableCompressCss() {
795  $this->compressCss = FALSE;
796  }
797 
803  public function enableConcatenateFiles() {
804  $this->concatenateFiles = TRUE;
805  }
806 
812  public function disableConcatenateFiles() {
813  $this->concatenateFiles = FALSE;
814  }
815 
821  public function enableConcatenateJavascript() {
822  $this->concatenateJavascript = TRUE;
823  }
824 
830  public function disableConcatenateJavascript() {
831  $this->concatenateJavascript = FALSE;
832  }
833 
839  public function enableConcatenateCss() {
840  $this->concatenateCss = TRUE;
841  }
842 
848  public function disableConcatenateCss() {
849  $this->concatenateCss = FALSE;
850  }
851 
858  $this->removeLineBreaksFromTemplate = TRUE;
859  }
860 
867  $this->removeLineBreaksFromTemplate = FALSE;
868  }
869 
876  public function enableDebugMode() {
877  $this->compressJavascript = FALSE;
878  $this->compressCss = FALSE;
879  $this->concatenateFiles = FALSE;
880  $this->removeLineBreaksFromTemplate = FALSE;
881  $this->enableExtCoreDebug = TRUE;
882  $this->enableExtJsDebug = TRUE;
883  $this->enableJqueryDebug = TRUE;
884  $this->enableSvgDebug = TRUE;
885  }
886 
887  /*****************************************************/
888  /* */
889  /* Public Getters */
890  /* */
891  /* */
892  /*****************************************************/
898  public function getTitle() {
899  return $this->title;
900  }
901 
907  public function getCharSet() {
908  return $this->charSet;
909  }
910 
916  public function getLanguage() {
917  return $this->lang;
918  }
919 
925  public function getRenderXhtml() {
926  return $this->renderXhtml;
927  }
928 
934  public function getHtmlTag() {
935  return $this->htmlTag;
936  }
937 
943  public function getMetaCharsetTag() {
944  return $this->metaCharsetTag;
945  }
946 
952  public function getHeadTag() {
953  return $this->headTag;
954  }
955 
961  public function getFavIcon() {
962  return $this->favIcon;
963  }
964 
970  public function getIconMimeType() {
971  return $this->iconMimeType;
972  }
973 
979  public function getBaseUrl() {
980  return $this->baseUrl;
981  }
982 
988  public function getTemplateFile() {
989  return $this->templateFile;
990  }
991 
997  public function getMoveJsFromHeaderToFooter() {
999  }
1000 
1006  public function getCompressJavascript() {
1008  }
1009 
1015  public function getCompressCss() {
1016  return $this->compressCss;
1017  }
1018 
1024  public function getConcatenateFiles() {
1025  return $this->concatenateFiles;
1026  }
1027 
1033  public function getConcatenateJavascript() {
1035  }
1036 
1042  public function getConcatenateCss() {
1043  return $this->concatenateCss;
1044  }
1045 
1053  }
1054 
1060  public function getBodyContent() {
1061  return $this->bodyContent;
1062  }
1063 
1069  public function getPrototypePath() {
1070  return $this->prototypePath;
1071  }
1072 
1078  public function getScriptaculousPath() {
1079  return $this->scriptaculousPath;
1080  }
1081 
1087  public function getExtCorePath() {
1088  return $this->extCorePath;
1089  }
1090 
1096  public function getExtJsPath() {
1097  return $this->extJsPath;
1098  }
1099 
1105  public function getSvgPath() {
1106  return $this->svgPath;
1107  }
1108 
1114  public function getInlineLanguageLabels() {
1116  }
1117 
1123  public function getInlineLanguageLabelFiles() {
1125  }
1126 
1127  /*****************************************************/
1128  /* */
1129  /* Public Functions to add Data */
1130  /* */
1131  /* */
1132  /*****************************************************/
1139  public function addMetaTag($meta) {
1140  if (!in_array($meta, $this->metaTags)) {
1141  $this->metaTags[] = $meta;
1142  }
1143  }
1144 
1151  public function addInlineComment($comment) {
1152  if (!in_array($comment, $this->inlineComments)) {
1153  $this->inlineComments[] = $comment;
1154  }
1155  }
1156 
1163  public function addHeaderData($data) {
1164  if (!in_array($data, $this->headerData)) {
1165  $this->headerData[] = $data;
1166  }
1167  }
1168 
1175  public function addFooterData($data) {
1176  if (!in_array($data, $this->footerData)) {
1177  $this->footerData[] = $data;
1178  }
1179  }
1180 
1194  public function addJsLibrary($name, $file, $type = 'text/javascript', $compress = FALSE, $forceOnTop = FALSE, $allWrap = '', $excludeFromConcatenation = FALSE, $splitChar = '|') {
1195  if (!$type) {
1196  $type = 'text/javascript';
1197  }
1198  if (!in_array(strtolower($name), $this->jsLibs)) {
1199  $this->jsLibs[strtolower($name)] = array(
1200  'file' => $file,
1201  'type' => $type,
1202  'section' => self::PART_HEADER,
1203  'compress' => $compress,
1204  'forceOnTop' => $forceOnTop,
1205  'allWrap' => $allWrap,
1206  'excludeFromConcatenation' => $excludeFromConcatenation,
1207  'splitChar' => $splitChar
1208  );
1209  }
1210  }
1211 
1225  public function addJsFooterLibrary($name, $file, $type = 'text/javascript', $compress = FALSE, $forceOnTop = FALSE, $allWrap = '', $excludeFromConcatenation = FALSE, $splitChar = '|') {
1226  if (!$type) {
1227  $type = 'text/javascript';
1228  }
1229  if (!in_array(strtolower($name), $this->jsLibs)) {
1230  $this->jsLibs[strtolower($name)] = array(
1231  'file' => $file,
1232  'type' => $type,
1233  'section' => self::PART_FOOTER,
1234  'compress' => $compress,
1235  'forceOnTop' => $forceOnTop,
1236  'allWrap' => $allWrap,
1237  'excludeFromConcatenation' => $excludeFromConcatenation,
1238  'splitChar' => $splitChar
1239  );
1240  }
1241  }
1242 
1255  public function addJsFile($file, $type = 'text/javascript', $compress = TRUE, $forceOnTop = FALSE, $allWrap = '', $excludeFromConcatenation = FALSE, $splitChar = '|') {
1256  if (!$type) {
1257  $type = 'text/javascript';
1258  }
1259  if (!isset($this->jsFiles[$file])) {
1260  if (strpos($file, 'ajax.php?') !== FALSE) {
1261  $compress = FALSE;
1262  }
1263  $this->jsFiles[$file] = array(
1264  'file' => $file,
1265  'type' => $type,
1266  'section' => self::PART_HEADER,
1267  'compress' => $compress,
1268  'forceOnTop' => $forceOnTop,
1269  'allWrap' => $allWrap,
1270  'excludeFromConcatenation' => $excludeFromConcatenation,
1271  'splitChar' => $splitChar
1272  );
1273  }
1274  }
1275 
1288  public function addJsFooterFile($file, $type = 'text/javascript', $compress = TRUE, $forceOnTop = FALSE, $allWrap = '', $excludeFromConcatenation = FALSE, $splitChar = '|') {
1289  if (!$type) {
1290  $type = 'text/javascript';
1291  }
1292  if (!isset($this->jsFiles[$file])) {
1293  if (strpos($file, 'ajax.php?') !== FALSE) {
1294  $compress = FALSE;
1295  }
1296  $this->jsFiles[$file] = array(
1297  'file' => $file,
1298  'type' => $type,
1299  'section' => self::PART_FOOTER,
1300  'compress' => $compress,
1301  'forceOnTop' => $forceOnTop,
1302  'allWrap' => $allWrap,
1303  'excludeFromConcatenation' => $excludeFromConcatenation,
1304  'splitChar' => $splitChar
1305  );
1306  }
1307  }
1308 
1318  public function addJsInlineCode($name, $block, $compress = TRUE, $forceOnTop = FALSE) {
1319  if (!isset($this->jsInline[$name]) && !empty($block)) {
1320  $this->jsInline[$name] = array(
1321  'code' => $block . LF,
1322  'section' => self::PART_HEADER,
1323  'compress' => $compress,
1324  'forceOnTop' => $forceOnTop
1325  );
1326  }
1327  }
1328 
1338  public function addJsFooterInlineCode($name, $block, $compress = TRUE, $forceOnTop = FALSE) {
1339  if (!isset($this->jsInline[$name]) && !empty($block)) {
1340  $this->jsInline[$name] = array(
1341  'code' => $block . LF,
1342  'section' => self::PART_FOOTER,
1343  'compress' => $compress,
1344  'forceOnTop' => $forceOnTop
1345  );
1346  }
1347  }
1348 
1356  public function addExtOnReadyCode($block, $forceOnTop = FALSE) {
1357  if (!in_array($block, $this->extOnReadyCode)) {
1358  if ($forceOnTop) {
1359  array_unshift($this->extOnReadyCode, $block);
1360  } else {
1361  $this->extOnReadyCode[] = $block;
1362  }
1363  }
1364  }
1365 
1372  public function addExtDirectCode(array $filterNamespaces = array()) {
1373  if ($this->extDirectCodeAdded) {
1374  return;
1375  }
1376  $this->extDirectCodeAdded = TRUE;
1377  if (count($filterNamespaces) === 0) {
1378  $filterNamespaces = array('TYPO3');
1379  }
1380  // For ExtDirect we need flash message support
1381  $this->addJsFile(GeneralUtility::resolveBackPath($this->backPath . 'sysext/backend/Resources/Public/JavaScript/flashmessages.js'));
1382  // Add language labels for ExtDirect
1383  if (TYPO3_MODE === 'FE') {
1384  $this->addInlineLanguageLabelArray(array(
1385  'extDirect_timeoutHeader' => $GLOBALS['TSFE']->sL('LLL:EXT:lang/locallang_misc.xlf:extDirect_timeoutHeader'),
1386  'extDirect_timeoutMessage' => $GLOBALS['TSFE']->sL('LLL:EXT:lang/locallang_misc.xlf:extDirect_timeoutMessage')
1387  ));
1388  } else {
1389  $this->addInlineLanguageLabelArray(array(
1390  'extDirect_timeoutHeader' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_misc.xlf:extDirect_timeoutHeader'),
1391  'extDirect_timeoutMessage' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_misc.xlf:extDirect_timeoutMessage')
1392  ));
1393  }
1394  $token = ($api = '');
1395  if (TYPO3_MODE === 'BE') {
1397  $token = $formprotection->generateToken('extDirect');
1398  }
1400  $extDirect = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\ExtDirect\\ExtDirectApi');
1401  $api = $extDirect->getApiPhp($filterNamespaces);
1402  if ($api) {
1403  $this->addJsInlineCode('TYPO3ExtDirectAPI', $api, FALSE);
1404  }
1405  // Note: we need to iterate thru the object, because the addProvider method
1406  // does this only with multiple arguments
1407  $this->addExtOnReadyCode('
1408  (function() {
1409  TYPO3.ExtDirectToken = "' . $token . '";
1410  for (var api in Ext.app.ExtDirectAPI) {
1411  var provider = Ext.Direct.addProvider(Ext.app.ExtDirectAPI[api]);
1412  provider.on("beforecall", function(provider, transaction, meta) {
1413  if (transaction.data) {
1414  transaction.data[transaction.data.length] = TYPO3.ExtDirectToken;
1415  } else {
1416  transaction.data = [TYPO3.ExtDirectToken];
1417  }
1418  });
1419 
1420  provider.on("call", function(provider, transaction, meta) {
1421  if (transaction.isForm) {
1422  transaction.params.securityToken = TYPO3.ExtDirectToken;
1423  }
1424  });
1425  }
1426  })();
1427 
1428  var extDirectDebug = function(message, header, group) {
1429  var TYPO3ViewportInstance = null;
1430 
1431  if (top && top.TYPO3 && typeof top.TYPO3.Backend === "object") {
1432  TYPO3ViewportInstance = top.TYPO3.Backend;
1433  } else if (typeof TYPO3 === "object" && typeof TYPO3.Backend === "object") {
1434  TYPO3ViewportInstance = TYPO3.Backend;
1435  }
1436 
1437  if (TYPO3ViewportInstance !== null) {
1438  TYPO3ViewportInstance.DebugConsole.addTab(message, header, group);
1439  } else if (typeof console === "object") {
1440  console.log(message);
1441  } else {
1442  document.write(message);
1443  }
1444  };
1445 
1446  Ext.Direct.on("exception", function(event) {
1447  if (event.code === Ext.Direct.exceptions.TRANSPORT && !event.where) {
1448  TYPO3.Flashmessage.display(
1449  TYPO3.Severity.error,
1450  TYPO3.l10n.localize("extDirect_timeoutHeader"),
1451  TYPO3.l10n.localize("extDirect_timeoutMessage"),
1452  30
1453  );
1454  } else {
1455  var backtrace = "";
1456  if (event.code === "parse") {
1457  extDirectDebug(
1458  "<p>" + event.xhr.responseText + "<\\/p>",
1459  event.type,
1460  "ExtDirect - Exception"
1461  );
1462  } else if (event.code === "router") {
1463  TYPO3.Flashmessage.display(
1464  TYPO3.Severity.error,
1465  event.code,
1466  event.message,
1467  30
1468  );
1469  } else if (event.where) {
1470  backtrace = "<p style=\\"margin-top: 20px;\\">" +
1471  "<strong>Backtrace:<\\/strong><br \\/>" +
1472  event.where.replace(/#/g, "<br \\/>#") +
1473  "<\\/p>";
1474  extDirectDebug(
1475  "<p>" + event.message + "<\\/p>" + backtrace,
1476  event.method,
1477  "ExtDirect - Exception"
1478  );
1479  }
1480 
1481 
1482  }
1483  });
1484 
1485  Ext.Direct.on("event", function(event, provider) {
1486  if (typeof event.debug !== "undefined" && event.debug !== "") {
1487  extDirectDebug(event.debug, event.method, "ExtDirect - Debug");
1488  }
1489  });
1490  ', TRUE);
1491  }
1492 
1507  public function addCssFile($file, $rel = 'stylesheet', $media = 'all', $title = '', $compress = TRUE, $forceOnTop = FALSE, $allWrap = '', $excludeFromConcatenation = FALSE, $splitChar = '|') {
1508  if (!isset($this->cssFiles[$file])) {
1509  $this->cssFiles[$file] = array(
1510  'file' => $file,
1511  'rel' => $rel,
1512  'media' => $media,
1513  'title' => $title,
1514  'compress' => $compress,
1515  'forceOnTop' => $forceOnTop,
1516  'allWrap' => $allWrap,
1517  'excludeFromConcatenation' => $excludeFromConcatenation,
1518  'splitChar' => $splitChar
1519  );
1520  }
1521  }
1522 
1537  public function addCssLibrary($file, $rel = 'stylesheet', $media = 'all', $title = '', $compress = TRUE, $forceOnTop = FALSE, $allWrap = '', $excludeFromConcatenation = FALSE, $splitChar = '|') {
1538  if (!isset($this->cssLibs[$file])) {
1539  $this->cssLibs[$file] = array(
1540  'file' => $file,
1541  'rel' => $rel,
1542  'media' => $media,
1543  'title' => $title,
1544  'compress' => $compress,
1545  'forceOnTop' => $forceOnTop,
1546  'allWrap' => $allWrap,
1547  'excludeFromConcatenation' => $excludeFromConcatenation,
1548  'splitChar' => $splitChar
1549  );
1550  }
1551  }
1552 
1562  public function addCssInlineBlock($name, $block, $compress = FALSE, $forceOnTop = FALSE) {
1563  if (!isset($this->cssInline[$name]) && !empty($block)) {
1564  $this->cssInline[$name] = array(
1565  'code' => $block,
1566  'compress' => $compress,
1567  'forceOnTop' => $forceOnTop
1568  );
1569  }
1570  }
1571 
1581  public function loadJquery($version = NULL, $source = NULL, $namespace = self::JQUERY_NAMESPACE_DEFAULT) {
1582  // Set it to the version that is shipped with the TYPO3 core
1583  if ($version === NULL || $version === 'latest') {
1584  $version = self::JQUERY_VERSION_LATEST;
1585  }
1586  // Check if the source is set, otherwise set it to "default"
1587  if ($source === NULL) {
1588  $source = 'local';
1589  }
1590  if ($source === 'local' && !in_array($version, $this->availableLocalJqueryVersions)) {
1591  throw new \UnexpectedValueException('The requested jQuery version is not available in the local filesystem.', 1341505305);
1592  }
1593  if (!preg_match('/^[a-zA-Z0-9]+$/', $namespace)) {
1594  throw new \UnexpectedValueException('The requested namespace contains non alphanumeric characters.', 1341571604);
1595  }
1596  $this->jQueryVersions[$namespace] = array(
1597  'version' => $version,
1598  'source' => $source
1599  );
1600  }
1601 
1610  public function loadRequireJs() {
1611 
1612  // load all paths to map to package names / namespaces
1613  if (count($this->requireJsConfig) === 0) {
1614  // first, load all paths for the namespaces, and configure contrib libs.
1615  $this->requireJsConfig['paths'] = array(
1616  'jquery-ui' => 'contrib/jqueryui',
1617  'jquery' => 'contrib/jquery'
1618  );
1619  // get all extensions that are loaded
1621  foreach ($loadedExtensions as $packageName) {
1622  $fullJsPath = 'EXT:' . $packageName . '/Resources/Public/JavaScript/';
1623  $fullJsPath = GeneralUtility::getFileAbsFileName($fullJsPath);
1624  $fullJsPath = \TYPO3\CMS\Core\Utility\PathUtility::getRelativePath(PATH_typo3, $fullJsPath);
1625  $fullJsPath = rtrim($fullJsPath, '/');
1626  if ($fullJsPath) {
1627  $this->requireJsConfig['paths']['TYPO3/CMS/' . GeneralUtility::underscoredToUpperCamelCase($packageName)] = $this->backPath . $fullJsPath;
1628  }
1629  }
1630 
1631  // check if additional AMD modules need to be loaded if a single AMD module is initialized
1632  if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['RequireJS']['postInitializationModules'])) {
1633  $this->addInlineSettingArray('RequireJS.PostInitializationModules', $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['RequireJS']['postInitializationModules']);
1634  }
1635  }
1636 
1637  $this->addRequireJs = TRUE;
1638  }
1639 
1655  public function addRequireJsConfiguration(array $configuration) {
1656  \TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($this->requireJsConfig, $configuration);
1657  }
1658 
1674  public function loadRequireJsModule($mainModuleName) {
1675 
1676  // make sure requireJS is initialized
1677  $this->loadRequireJs();
1678 
1679  // execute the main module
1680  $this->addJsInlineCode('RequireJS-Module-' . $mainModuleName, 'require(["' . $mainModuleName . '"]);');
1681  }
1682 
1688  public function loadPrototype() {
1689  $this->addPrototype = TRUE;
1690  }
1691 
1698  public function loadScriptaculous($modules = 'all') {
1699  // Scriptaculous require prototype, so load prototype too.
1700  $this->addPrototype = TRUE;
1701  $this->addScriptaculous = TRUE;
1702  if ($modules) {
1703  if ($modules == 'all') {
1704  foreach ($this->addScriptaculousModules as $key => $value) {
1705  $this->addScriptaculousModules[$key] = TRUE;
1706  }
1707  } else {
1708  $mods = GeneralUtility::trimExplode(',', $modules);
1709  foreach ($mods as $mod) {
1710  if (isset($this->addScriptaculousModules[strtolower($mod)])) {
1711  $this->addScriptaculousModules[strtolower($mod)] = TRUE;
1712  }
1713  }
1714  }
1715  }
1716  }
1717 
1726  public function loadExtJS($css = TRUE, $theme = TRUE, $adapter = '') {
1727  if ($adapter) {
1728  // Empty $adapter will always load the ext adapter
1729  switch (GeneralUtility::strtolower(trim($adapter))) {
1730  case self::EXTJS_ADAPTER_YUI:
1731  $this->extJSadapter = 'yui/ext-yui-adapter.js';
1732  break;
1733  case self::EXTJS_ADAPTER_PROTOTYPE:
1734  $this->extJSadapter = 'prototype/ext-prototype-adapter.js';
1735  break;
1736  case self::EXTJS_ADAPTER_JQUERY:
1737  $this->extJSadapter = 'jquery/ext-jquery-adapter.js';
1738  break;
1739  }
1740  }
1741  $this->addExtJS = TRUE;
1742  $this->extJStheme = $theme;
1743  $this->extJScss = $css;
1744  }
1745 
1752  public function enableExtJSQuickTips() {
1753  $this->enableExtJSQuickTips = TRUE;
1754  }
1755 
1761  public function loadExtCore() {
1762  $this->addExtCore = TRUE;
1763  }
1764 
1770  public function loadSvg() {
1771  $this->addSvg = TRUE;
1772  }
1773 
1779  public function enableSvgDebug() {
1780  $this->enableSvgDebug = TRUE;
1781  }
1782 
1788  public function svgForceFlash() {
1789  $this->addMetaTag('<meta name="svg.render.forceflash" content="true" />');
1790  }
1791 
1797  public function enableExtJsDebug() {
1798  $this->enableExtJsDebug = TRUE;
1799  }
1800 
1806  public function enableExtCoreDebug() {
1807  $this->enableExtCoreDebug = TRUE;
1808  }
1809 
1819  public function addInlineLanguageLabel($key, $value) {
1820  $this->inlineLanguageLabels[$key] = $value;
1821  }
1822 
1832  public function addInlineLanguageLabelArray(array $array) {
1833  $this->inlineLanguageLabels = array_merge($this->inlineLanguageLabels, $array);
1834  }
1835 
1845  public function addInlineLanguageLabelFile($fileRef, $selectionPrefix = '', $stripFromSelectionName = '', $errorMode = 0) {
1846  $index = md5($fileRef . $selectionPrefix . $stripFromSelectionName);
1847  if ($fileRef && !isset($this->inlineLanguageLabelFiles[$index])) {
1848  $this->inlineLanguageLabelFiles[$index] = array(
1849  'fileRef' => $fileRef,
1850  'selectionPrefix' => $selectionPrefix,
1851  'stripFromSelectionName' => $stripFromSelectionName,
1852  'errorMode' => $errorMode
1853  );
1854  }
1855  }
1856 
1867  public function addInlineSetting($namespace, $key, $value) {
1868  if ($namespace) {
1869  if (strpos($namespace, '.')) {
1870  $parts = explode('.', $namespace);
1871  $a = &$this->inlineSettings;
1872  foreach ($parts as $part) {
1873  $a = &$a[$part];
1874  }
1875  $a[$key] = $value;
1876  } else {
1877  $this->inlineSettings[$namespace][$key] = $value;
1878  }
1879  } else {
1880  $this->inlineSettings[$key] = $value;
1881  }
1882  }
1883 
1894  public function addInlineSettingArray($namespace, array $array) {
1895  if ($namespace) {
1896  if (strpos($namespace, '.')) {
1897  $parts = explode('.', $namespace);
1898  $a = &$this->inlineSettings;
1899  foreach ($parts as $part) {
1900  $a = &$a[$part];
1901  }
1902  $a = array_merge((array) $a, $array);
1903  } else {
1904  $this->inlineSettings[$namespace] = array_merge((array) $this->inlineSettings[$namespace], $array);
1905  }
1906  } else {
1907  $this->inlineSettings = array_merge($this->inlineSettings, $array);
1908  }
1909  }
1910 
1917  public function addBodyContent($content) {
1918  $this->bodyContent .= $content;
1919  }
1920 
1921  /*****************************************************/
1922  /* */
1923  /* Render Functions */
1924  /* */
1925  /*****************************************************/
1932  public function render($part = self::PART_COMPLETE) {
1933  $this->prepareRendering();
1935  $metaTags = implode(LF, $this->metaTags);
1937  $template = $this->getTemplateForPart($part);
1938 
1939  // The page renderer needs a full reset, even when only rendering one part of the page
1940  // This means that you can only register footer files *after* the header has been already rendered.
1941  // In case you render the footer part first, header files can only be added *after* the footer has been rendered
1942  $this->reset();
1943  return trim(\TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($template, $markerArray, '###|###'));
1944  }
1945 
1953  public function renderPageWithUncachedObjects($substituteHash) {
1954  $this->prepareRendering();
1955  $markerArray = $this->getPreparedMarkerArrayForPageWithUncachedObjects($substituteHash);
1956  $template = $this->getTemplateForPart(self::PART_COMPLETE);
1957  return trim(\TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($template, $markerArray, '###|###'));
1958  }
1959 
1969  public function renderJavaScriptAndCssForProcessingOfUncachedContentObjects($cachedPageContent, $substituteHash) {
1970  $this->prepareRendering();
1972  $title = $this->title ? str_replace('|', htmlspecialchars($this->title), $this->titleTag) : '';
1973  $markerArray = array(
1974  '<!-- ###TITLE' . $substituteHash . '### -->' => $title,
1975  '<!-- ###CSS_LIBS' . $substituteHash . '### -->' => $cssLibs,
1976  '<!-- ###CSS_INCLUDE' . $substituteHash . '### -->' => $cssFiles,
1977  '<!-- ###CSS_INLINE' . $substituteHash . '### -->' => $cssInline,
1978  '<!-- ###JS_INLINE' . $substituteHash . '### -->' => $jsInline,
1979  '<!-- ###JS_INCLUDE' . $substituteHash . '### -->' => $jsFiles,
1980  '<!-- ###JS_LIBS' . $substituteHash . '### -->' => $jsLibs,
1981  '<!-- ###HEADERDATA' . $substituteHash . '### -->' => implode(LF, $this->headerData),
1982  '<!-- ###FOOTERDATA' . $substituteHash . '### -->' => implode(LF, $this->footerData),
1983  '<!-- ###JS_LIBS_FOOTER' . $substituteHash . '### -->' => $jsFooterLibs,
1984  '<!-- ###JS_INCLUDE_FOOTER' . $substituteHash . '### -->' => $jsFooterFiles,
1985  '<!-- ###JS_INLINE_FOOTER' . $substituteHash . '### -->' => $jsFooterInline
1986  );
1987  foreach ($markerArray as $placeHolder => $content) {
1988  $cachedPageContent = str_replace($placeHolder, $content, $cachedPageContent);
1989  }
1990  $this->reset();
1991  return $cachedPageContent;
1992  }
1993 
2001  protected function prepareRendering() {
2002  if ($this->getRenderXhtml()) {
2003  $this->endingSlash = ' /';
2004  } else {
2005  $this->metaCharsetTag = str_replace(' />', '>', $this->metaCharsetTag);
2006  $this->baseUrlTag = str_replace(' />', '>', $this->baseUrlTag);
2007  $this->shortcutTag = str_replace(' />', '>', $this->shortcutTag);
2008  $this->endingSlash = '';
2009  }
2010  }
2011 
2017  protected function renderJavaScriptAndCss() {
2018  $this->executePreRenderHook();
2019  $mainJsLibs = $this->renderMainJavaScriptLibraries();
2020  if ($this->concatenateFiles || $this->concatenateJavascript || $this->concatenateCss) {
2021  // Do the file concatenation
2022  $this->doConcatenate();
2023  }
2024  if ($this->compressCss || $this->compressJavascript) {
2025  // Do the file compression
2026  $this->doCompress();
2027  }
2029  $cssLibs = $this->renderCssLibraries();
2030  $cssFiles = $this->renderCssFiles();
2031  $cssInline = $this->renderCssInline();
2033  list($jsFiles, $jsFooterFiles) = $this->renderJavaScriptFiles();
2035  $jsLibs = $mainJsLibs . $jsLibs;
2036  if ($this->moveJsFromHeaderToFooter) {
2038  $jsLibs = '';
2040  $jsFiles = '';
2042  $jsInline = '';
2043  }
2046  }
2047 
2064  $markerArray = array(
2065  'XMLPROLOG_DOCTYPE' => $this->xmlPrologAndDocType,
2066  'HTMLTAG' => $this->htmlTag,
2067  'HEADTAG' => $this->headTag,
2068  'METACHARSET' => $this->charSet ? str_replace('|', htmlspecialchars($this->charSet), $this->metaCharsetTag) : '',
2069  'INLINECOMMENT' => $this->inlineComments ? LF . LF . '<!-- ' . LF . implode(LF, $this->inlineComments) . '-->' . LF . LF : '',
2070  'BASEURL' => $this->baseUrl ? str_replace('|', $this->baseUrl, $this->baseUrlTag) : '',
2071  'SHORTCUT' => $this->favIcon ? sprintf($this->shortcutTag, htmlspecialchars($this->favIcon), $this->iconMimeType) : '',
2072  'CSS_LIBS' => $cssLibs,
2073  'CSS_INCLUDE' => $cssFiles,
2074  'CSS_INLINE' => $cssInline,
2075  'JS_INLINE' => $jsInline,
2076  'JS_INCLUDE' => $jsFiles,
2077  'JS_LIBS' => $jsLibs,
2078  'TITLE' => $this->title ? str_replace('|', htmlspecialchars($this->title), $this->titleTag) : '',
2079  'META' => $metaTags,
2080  'HEADERDATA' => $this->headerData ? implode(LF, $this->headerData) : '',
2081  'FOOTERDATA' => $this->footerData ? implode(LF, $this->footerData) : '',
2082  'JS_LIBS_FOOTER' => $jsFooterLibs,
2083  'JS_INCLUDE_FOOTER' => $jsFooterFiles,
2084  'JS_INLINE_FOOTER' => $jsFooterInline,
2085  'BODY' => $this->bodyContent
2086  );
2087  $markerArray = array_map('trim', $markerArray);
2088  return $markerArray;
2089  }
2090 
2097  protected function getPreparedMarkerArrayForPageWithUncachedObjects($substituteHash) {
2098  $markerArray = array(
2099  'XMLPROLOG_DOCTYPE' => $this->xmlPrologAndDocType,
2100  'HTMLTAG' => $this->htmlTag,
2101  'HEADTAG' => $this->headTag,
2102  'METACHARSET' => $this->charSet ? str_replace('|', htmlspecialchars($this->charSet), $this->metaCharsetTag) : '',
2103  'INLINECOMMENT' => $this->inlineComments ? LF . LF . '<!-- ' . LF . implode(LF, $this->inlineComments) . '-->' . LF . LF : '',
2104  'BASEURL' => $this->baseUrl ? str_replace('|', $this->baseUrl, $this->baseUrlTag) : '',
2105  'SHORTCUT' => $this->favIcon ? sprintf($this->shortcutTag, htmlspecialchars($this->favIcon), $this->iconMimeType) : '',
2106  'META' => implode(LF, $this->metaTags),
2107  'BODY' => $this->bodyContent,
2108  'TITLE' => '<!-- ###TITLE' . $substituteHash . '### -->',
2109  'CSS_LIBS' => '<!-- ###CSS_LIBS' . $substituteHash . '### -->',
2110  'CSS_INCLUDE' => '<!-- ###CSS_INCLUDE' . $substituteHash . '### -->',
2111  'CSS_INLINE' => '<!-- ###CSS_INLINE' . $substituteHash . '### -->',
2112  'JS_INLINE' => '<!-- ###JS_INLINE' . $substituteHash . '### -->',
2113  'JS_INCLUDE' => '<!-- ###JS_INCLUDE' . $substituteHash . '### -->',
2114  'JS_LIBS' => '<!-- ###JS_LIBS' . $substituteHash . '### -->',
2115  'HEADERDATA' => '<!-- ###HEADERDATA' . $substituteHash . '### -->',
2116  'FOOTERDATA' => '<!-- ###FOOTERDATA' . $substituteHash . '### -->',
2117  'JS_LIBS_FOOTER' => '<!-- ###JS_LIBS_FOOTER' . $substituteHash . '### -->',
2118  'JS_INCLUDE_FOOTER' => '<!-- ###JS_INCLUDE_FOOTER' . $substituteHash . '### -->',
2119  'JS_INLINE_FOOTER' => '<!-- ###JS_INLINE_FOOTER' . $substituteHash . '### -->'
2120  );
2121  $markerArray = array_map('trim', $markerArray);
2122  return $markerArray;
2123  }
2124 
2131  protected function getTemplateForPart($part) {
2132  $templateFile = GeneralUtility::getFileAbsFileName($this->templateFile, TRUE);
2134  if ($this->removeLineBreaksFromTemplate) {
2135  $template = strtr($template, array(LF => '', CR => ''));
2136  }
2137  if ($part !== self::PART_COMPLETE) {
2138  $templatePart = explode('###BODY###', $template);
2139  $template = $templatePart[$part - 1];
2140  }
2141  return $template;
2142  }
2143 
2150  protected function renderMainJavaScriptLibraries() {
2151  $out = '';
2152 
2153  // Include RequireJS
2154  if ($this->addRequireJs) {
2155  // load the paths of the requireJS configuration
2156  $out .= GeneralUtility::wrapJS('var require = ' . json_encode($this->requireJsConfig)) . LF;
2157  // directly after that, include the require.js file
2158  $out .= '<script src="' . $this->processJsFile(($this->backPath . $this->requireJsPath . 'require.js')) . '" type="text/javascript"></script>' . LF;
2159  }
2160 
2161  if ($this->addSvg) {
2162  $out .= '<script src="' . $this->processJsFile(($this->backPath . $this->svgPath . 'svg.js')) . '" data-path="' . $this->backPath . $this->svgPath . '"' . ($this->enableSvgDebug ? ' data-debug="true"' : '') . '></script>' . LF;
2163  }
2164  // Include jQuery Core for each namespace, depending on the version and source
2165  if (!empty($this->jQueryVersions)) {
2166  foreach ($this->jQueryVersions as $namespace => $jQueryVersion) {
2167  $out .= $this->renderJqueryScriptTag($jQueryVersion['version'], $jQueryVersion['source'], $namespace);
2168  }
2169  }
2170  if ($this->addPrototype) {
2171  $out .= '<script src="' . $this->processJsFile(($this->backPath . $this->prototypePath . 'prototype.js')) . '" type="text/javascript"></script>' . LF;
2172  unset($this->jsFiles[$this->backPath . $this->prototypePath . 'prototype.js']);
2173  }
2174  if ($this->addScriptaculous) {
2175  $mods = array();
2176  foreach ($this->addScriptaculousModules as $key => $value) {
2177  if ($this->addScriptaculousModules[$key]) {
2178  $mods[] = $key;
2179  }
2180  }
2181  // Resolve dependencies
2182  if (in_array('dragdrop', $mods) || in_array('controls', $mods)) {
2183  $mods = array_merge(array('effects'), $mods);
2184  }
2185  if (count($mods)) {
2186  foreach ($mods as $module) {
2187  $out .= '<script src="' . $this->processJsFile(($this->backPath . $this->scriptaculousPath . $module . '.js')) . '" type="text/javascript"></script>' . LF;
2188  unset($this->jsFiles[$this->backPath . $this->scriptaculousPath . $module . '.js']);
2189  }
2190  }
2191  $out .= '<script src="' . $this->processJsFile(($this->backPath . $this->scriptaculousPath . 'scriptaculous.js')) . '" type="text/javascript"></script>' . LF;
2192  unset($this->jsFiles[$this->backPath . $this->scriptaculousPath . 'scriptaculous.js']);
2193  }
2194  // Include extCore, but only if ExtJS is not included
2195  if ($this->addExtCore && !$this->addExtJS) {
2196  $out .= '<script src="' . $this->processJsFile(($this->backPath . $this->extCorePath . 'ext-core' . ($this->enableExtCoreDebug ? '-debug' : '') . '.js')) . '" type="text/javascript"></script>' . LF;
2197  unset($this->jsFiles[$this->backPath . $this->extCorePath . 'ext-core' . ($this->enableExtCoreDebug ? '-debug' : '') . '.js']);
2198  }
2199  // Include extJS
2200  if ($this->addExtJS) {
2201  // Use the base adapter all the time
2202  $out .= '<script src="' . $this->processJsFile(($this->backPath . $this->extJsPath . 'adapter/' . ($this->enableExtJsDebug ? str_replace('.js', '-debug.js', $this->extJSadapter) : $this->extJSadapter))) . '" type="text/javascript"></script>' . LF;
2203  $out .= '<script src="' . $this->processJsFile(($this->backPath . $this->extJsPath . 'ext-all' . ($this->enableExtJsDebug ? '-debug' : '') . '.js')) . '" type="text/javascript"></script>' . LF;
2204  // Add extJS localization
2205  // Load standard ISO mapping and modify for use with ExtJS
2206  $localeMap = $this->locales->getIsoMapping();
2207  $localeMap[''] = 'en';
2208  $localeMap['default'] = 'en';
2209  // Greek
2210  $localeMap['gr'] = 'el_GR';
2211  // Norwegian Bokmaal
2212  $localeMap['no'] = 'no_BO';
2213  // Swedish
2214  $localeMap['se'] = 'se_SV';
2215  $extJsLang = isset($localeMap[$this->lang]) ? $localeMap[$this->lang] : $this->lang;
2216  // TODO autoconvert file from UTF8 to current BE charset if necessary!!!!
2217  $extJsLocaleFile = $this->extJsPath . 'locale/ext-lang-' . $extJsLang . '.js';
2218  if (file_exists(PATH_typo3 . $extJsLocaleFile)) {
2219  $out .= '<script src="' . $this->processJsFile(($this->backPath . $extJsLocaleFile)) . '" type="text/javascript" charset="utf-8"></script>' . LF;
2220  }
2221  // Remove extjs from JScodeLibArray
2222  unset($this->jsFiles[$this->backPath . $this->extJsPath . 'ext-all.js'], $this->jsFiles[$this->backPath . $this->extJsPath . 'ext-all-debug.js']);
2223  }
2224  if (count($this->inlineLanguageLabelFiles)) {
2225  foreach ($this->inlineLanguageLabelFiles as $languageLabelFile) {
2226  $this->includeLanguageFileForInline($languageLabelFile['fileRef'], $languageLabelFile['selectionPrefix'], $languageLabelFile['stripFromSelectionName'], $languageLabelFile['errorMode']);
2227  }
2228  }
2229  $this->inlineLanguageLabelFiles = array();
2230  // Convert labels/settings back to UTF-8 since json_encode() only works with UTF-8:
2231  if ($this->getCharSet() !== 'utf-8') {
2232  if ($this->inlineLanguageLabels) {
2233  $this->csConvObj->convArray($this->inlineLanguageLabels, $this->getCharSet(), 'utf-8');
2234  }
2235  if ($this->inlineSettings) {
2236  $this->csConvObj->convArray($this->inlineSettings, $this->getCharSet(), 'utf-8');
2237  }
2238  }
2239  $inlineSettings = '';
2240  if (!(TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_AJAX)) {
2241  if (TYPO3_MODE === 'BE') {
2242  $this->addAjaxUrlsToInlineSettings();
2243  }
2244  $inlineSettings .= $this->inlineLanguageLabels ? 'TYPO3.lang = ' . json_encode($this->inlineLanguageLabels) . ';' : '';
2245  $inlineSettings .= $this->inlineSettings ? 'TYPO3.settings = ' . json_encode($this->inlineSettings) . ';' : '';
2246  }
2247  if ($this->addExtCore || $this->addExtJS) {
2248  // Set clear.gif, move it on top, add handler code
2249  $code = '';
2250  if (count($this->extOnReadyCode)) {
2251  foreach ($this->extOnReadyCode as $block) {
2252  $code .= $block;
2253  }
2254  }
2255  $out .= $this->inlineJavascriptWrap[0] . '
2256  Ext.ns("TYPO3");
2257  Ext.BLANK_IMAGE_URL = "' . htmlspecialchars(GeneralUtility::locationHeaderUrl(($this->backPath . 'gfx/clear.gif'))) . '";
2258  Ext.SSL_SECURE_URL = "' . htmlspecialchars(GeneralUtility::locationHeaderUrl(($this->backPath . 'gfx/clear.gif'))) . '";' . LF
2259  . $inlineSettings
2260  . 'Ext.onReady(function() {'
2261  . ($this->enableExtJSQuickTips ? 'Ext.QuickTips.init();' . LF : '')
2262  . $code
2263  . ' });'
2264  . $this->inlineJavascriptWrap[1];
2265  $this->extOnReadyCode = array();
2266  // Include TYPO3.l10n object
2267  if (TYPO3_MODE === 'BE') {
2268  $out .= '<script src="' . $this->processJsFile(($this->backPath . 'sysext/lang/Resources/Public/JavaScript/Typo3Lang.js')) . '" type="text/javascript" charset="utf-8"></script>' . LF;
2269  }
2270  if ($this->extJScss) {
2271  if (isset($GLOBALS['TBE_STYLES']['extJS']['all'])) {
2272  $this->addCssLibrary($this->backPath . $GLOBALS['TBE_STYLES']['extJS']['all'], 'stylesheet', 'all', '', TRUE);
2273  } else {
2274  $this->addCssLibrary($this->backPath . $this->extJsPath . 'resources/css/ext-all-notheme.css', 'stylesheet', 'all', '', TRUE);
2275  }
2276  }
2277  if ($this->extJStheme) {
2278  if (isset($GLOBALS['TBE_STYLES']['extJS']['theme'])) {
2279  $this->addCssLibrary($this->backPath . $GLOBALS['TBE_STYLES']['extJS']['theme'], 'stylesheet', 'all', '', TRUE);
2280  } else {
2281  $this->addCssLibrary($this->backPath . $this->extJsPath . 'resources/css/xtheme-blue.css', 'stylesheet', 'all', '', TRUE);
2282  }
2283  }
2284  } else {
2285  // no extJS loaded, but still inline settings
2286  if ($inlineSettings !== '') {
2287  // make sure the global TYPO3 is available
2288  $inlineSettings = 'var TYPO3 = TYPO3 || {};' . CRLF . $inlineSettings;
2289  $out .= $this->inlineJavascriptWrap[0] . $inlineSettings . $this->inlineJavascriptWrap[1];
2290  }
2291  }
2292  return $out;
2293  }
2294 
2298  protected function addAjaxUrlsToInlineSettings() {
2299  $ajaxUrls = array();
2300  foreach ($GLOBALS['TYPO3_CONF_VARS']['BE']['AJAX'] as $ajaxHandler => $_) {
2301  $ajaxUrls[$ajaxHandler] = BackendUtility::getAjaxUrl($ajaxHandler);
2302  }
2303  $this->inlineSettings['ajaxUrls'] = $ajaxUrls;
2304  }
2305 
2314  protected function renderJqueryScriptTag($version, $source, $namespace) {
2315  switch (TRUE) {
2316  case isset($this->jQueryCdnUrls[$source]):
2317  if ($this->enableJqueryDebug) {
2318  $minifyPart = '';
2319  } else {
2320  $minifyPart = '.min';
2321  }
2322  $jQueryFileName = sprintf($this->jQueryCdnUrls[$source], $version, $minifyPart);
2323  break;
2324  case $source === 'local':
2325  $jQueryFileName = $this->backPath . $this->jQueryPath . 'jquery-' . rawurlencode($version);
2326  if ($this->enableJqueryDebug) {
2327  $jQueryFileName .= '.js';
2328  } else {
2329  $jQueryFileName .= '.min.js';
2330  }
2331  break;
2332  default:
2333  $jQueryFileName = $source;
2334  }
2335  // Include the jQuery Core
2336  $scriptTag = '<script src="' . htmlspecialchars($jQueryFileName) . '" type="text/javascript"></script>' . LF;
2337  // Set the noConflict mode to be available via "TYPO3.jQuery" in all installations
2338  switch ($namespace) {
2339  case self::JQUERY_NAMESPACE_DEFAULT_NOCONFLICT:
2340  $scriptTag .= GeneralUtility::wrapJS('jQuery.noConflict();') . LF;
2341  break;
2342  case self::JQUERY_NAMESPACE_NONE:
2343  break;
2344  case self::JQUERY_NAMESPACE_DEFAULT:
2345 
2346  default:
2347  $scriptTag .= GeneralUtility::wrapJS('var TYPO3 = TYPO3 || {}; TYPO3.' . $namespace . ' = jQuery.noConflict(true);') . LF;
2348  }
2349  return $scriptTag;
2350  }
2351 
2357  protected function renderCssLibraries() {
2358  $cssFiles = '';
2359  if (count($this->cssLibs)) {
2360  foreach ($this->cssLibs as $file => $properties) {
2361  $file = GeneralUtility::resolveBackPath($file);
2363  $tag = '<link rel="' . htmlspecialchars($properties['rel'])
2364  . '" type="text/css" href="' . htmlspecialchars($file)
2365  . '" media="' . htmlspecialchars($properties['media']) . '"'
2366  . ($properties['title'] ? ' title="' . htmlspecialchars($properties['title']) . '"' : '')
2367  . $this->endingSlash . '>';
2368  if ($properties['allWrap']) {
2369  $wrapArr = explode($properties['splitChar'] ?: '|', $properties['allWrap'], 2);
2370  $tag = $wrapArr[0] . $tag . $wrapArr[1];
2371  }
2372  $tag .= LF;
2373  if ($properties['forceOnTop']) {
2374  $cssFiles = $tag . $cssFiles;
2375  } else {
2376  $cssFiles .= $tag;
2377  }
2378  }
2379  }
2380  return $cssFiles;
2381  }
2382 
2388  protected function renderCssFiles() {
2389  $cssFiles = '';
2390  if (count($this->cssFiles)) {
2391  foreach ($this->cssFiles as $file => $properties) {
2392  $file = GeneralUtility::resolveBackPath($file);
2394  $tag = '<link rel="' . htmlspecialchars($properties['rel'])
2395  . '" type="text/css" href="' . htmlspecialchars($file)
2396  . '" media="' . htmlspecialchars($properties['media']) . '"'
2397  . ($properties['title'] ? ' title="' . htmlspecialchars($properties['title']) . '"' : '')
2398  . $this->endingSlash . '>';
2399  if ($properties['allWrap']) {
2400  $wrapArr = explode($properties['splitChar'] ?: '|', $properties['allWrap'], 2);
2401  $tag = $wrapArr[0] . $tag . $wrapArr[1];
2402  }
2403  $tag .= LF;
2404  if ($properties['forceOnTop']) {
2405  $cssFiles = $tag . $cssFiles;
2406  } else {
2407  $cssFiles .= $tag;
2408  }
2409  }
2410  }
2411  return $cssFiles;
2412  }
2413 
2419  protected function renderCssInline() {
2420  $cssInline = '';
2421  if (count($this->cssInline)) {
2422  foreach ($this->cssInline as $name => $properties) {
2423  $cssCode = '/*' . htmlspecialchars($name) . '*/' . LF . $properties['code'] . LF;
2424  if ($properties['forceOnTop']) {
2425  $cssInline = $cssCode . $cssInline;
2426  } else {
2427  $cssInline .= $cssCode;
2428  }
2429  }
2430  $cssInline = $this->inlineCssWrap[0] . $cssInline . $this->inlineCssWrap[1];
2431  }
2432  return $cssInline;
2433  }
2434 
2441  $jsLibs = '';
2442  $jsFooterLibs = '';
2443  if (count($this->jsLibs)) {
2444  foreach ($this->jsLibs as $properties) {
2445  $properties['file'] = GeneralUtility::resolveBackPath($properties['file']);
2446  $properties['file'] = GeneralUtility::createVersionNumberedFilename($properties['file']);
2447  $tag = '<script src="' . htmlspecialchars($properties['file']) . '" type="' . htmlspecialchars($properties['type']) . '"></script>';
2448  if ($properties['allWrap']) {
2449  $wrapArr = explode($properties['splitChar'] ?: '|', $properties['allWrap'], 2);
2450  $tag = $wrapArr[0] . $tag . $wrapArr[1];
2451  }
2452  $tag .= LF;
2453  if ($properties['forceOnTop']) {
2454  if ($properties['section'] === self::PART_HEADER) {
2455  $jsLibs = $tag . $jsLibs;
2456  } else {
2457  $jsFooterLibs = $tag . $jsFooterLibs;
2458  }
2459  } else {
2460  if ($properties['section'] === self::PART_HEADER) {
2461  $jsLibs .= $tag;
2462  } else {
2463  $jsFooterLibs .= $tag;
2464  }
2465  }
2466  }
2467  }
2468  if ($this->moveJsFromHeaderToFooter) {
2470  $jsLibs = '';
2471  }
2472  return array($jsLibs, $jsFooterLibs);
2473  }
2474 
2480  protected function renderJavaScriptFiles() {
2481  $jsFiles = '';
2482  $jsFooterFiles = '';
2483  if (count($this->jsFiles)) {
2484  foreach ($this->jsFiles as $file => $properties) {
2485  $file = GeneralUtility::resolveBackPath($file);
2487  $tag = '<script src="' . htmlspecialchars($file) . '" type="' . htmlspecialchars($properties['type']) . '"></script>';
2488  if ($properties['allWrap']) {
2489  $wrapArr = explode($properties['splitChar'] ?: '|', $properties['allWrap'], 2);
2490  $tag = $wrapArr[0] . $tag . $wrapArr[1];
2491  }
2492  $tag .= LF;
2493  if ($properties['forceOnTop']) {
2494  if ($properties['section'] === self::PART_HEADER) {
2495  $jsFiles = $tag . $jsFiles;
2496  } else {
2497  $jsFooterFiles = $tag . $jsFooterFiles;
2498  }
2499  } else {
2500  if ($properties['section'] === self::PART_HEADER) {
2501  $jsFiles .= $tag;
2502  } else {
2503  $jsFooterFiles .= $tag;
2504  }
2505  }
2506  }
2507  }
2508  if ($this->moveJsFromHeaderToFooter) {
2510  $jsFiles = '';
2511  }
2512  return array($jsFiles, $jsFooterFiles);
2513  }
2514 
2520  protected function renderInlineJavaScript() {
2521  $jsInline = '';
2522  $jsFooterInline = '';
2523  if (count($this->jsInline)) {
2524  foreach ($this->jsInline as $name => $properties) {
2525  $jsCode = '/*' . htmlspecialchars($name) . '*/' . LF . $properties['code'] . LF;
2526  if ($properties['forceOnTop']) {
2527  if ($properties['section'] === self::PART_HEADER) {
2528  $jsInline = $jsCode . $jsInline;
2529  } else {
2530  $jsFooterInline = $jsCode . $jsFooterInline;
2531  }
2532  } else {
2533  if ($properties['section'] === self::PART_HEADER) {
2534  $jsInline .= $jsCode;
2535  } else {
2536  $jsFooterInline .= $jsCode;
2537  }
2538  }
2539  }
2540  }
2541  if ($jsInline) {
2542  $jsInline = $this->inlineJavascriptWrap[0] . $jsInline . $this->inlineJavascriptWrap[1];
2543  }
2544  if ($jsFooterInline) {
2545  $jsFooterInline = $this->inlineJavascriptWrap[0] . $jsFooterInline . $this->inlineJavascriptWrap[1];
2546  }
2547  if ($this->moveJsFromHeaderToFooter) {
2549  $jsInline = '';
2550  }
2551  return array($jsInline, $jsFooterInline);
2552  }
2553 
2564  protected function includeLanguageFileForInline($fileRef, $selectionPrefix = '', $stripFromSelectionName = '', $errorMode = 0) {
2565  if (!isset($this->lang) || !isset($this->charSet)) {
2566  throw new \RuntimeException('Language and character encoding are not set.', 1284906026);
2567  }
2568  $labelsFromFile = array();
2569  $allLabels = $this->readLLfile($fileRef, $errorMode);
2570  // Regular expression to strip the selection prefix and possibly something from the label name:
2571  $labelPattern = '#^' . preg_quote($selectionPrefix, '#') . '(' . preg_quote($stripFromSelectionName, '#') . ')?#';
2572  if ($allLabels !== FALSE) {
2573  // Merge language specific translations:
2574  if ($this->lang !== 'default' && isset($allLabels[$this->lang])) {
2575  $labels = array_merge($allLabels['default'], $allLabels[$this->lang]);
2576  } else {
2577  $labels = $allLabels['default'];
2578  }
2579  // Iterate through all locallang labels:
2580  foreach ($labels as $label => $value) {
2581  if ($selectionPrefix === '') {
2582  $labelsFromFile[$label] = $value;
2583  } elseif (strpos($label, $selectionPrefix) === 0) {
2584  preg_replace($labelPattern, '', $label);
2585  $labelsFromFile[$label] = $value;
2586  }
2587  }
2588  $this->inlineLanguageLabels = array_merge($this->inlineLanguageLabels, $labelsFromFile);
2589  }
2590  }
2591 
2599  protected function readLLfile($fileRef, $errorMode = 0) {
2600  if ($this->lang !== 'default') {
2601  $languages = array_reverse($this->languageDependencies);
2602  // At least we need to have English
2603  if (empty($languages)) {
2604  $languages[] = 'default';
2605  }
2606  } else {
2607  $languages = array('default');
2608  }
2609 
2610  $localLanguage = array();
2611  foreach ($languages as $language) {
2612  $tempLL = GeneralUtility::readLLfile($fileRef, $language, $this->charSet, $errorMode);
2613  $localLanguage['default'] = $tempLL['default'];
2614  if (!isset($localLanguage[$this->lang])) {
2615  $localLanguage[$this->lang] = $localLanguage['default'];
2616  }
2617  if ($this->lang !== 'default' && isset($tempLL[$language])) {
2618  // Merge current language labels onto labels from previous language
2619  // This way we have a labels with fall back applied
2620  \TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($localLanguage[$this->lang], $tempLL[$language], TRUE, FALSE);
2621  }
2622  }
2623 
2624  return $localLanguage;
2625  }
2626 
2627 
2628  /*****************************************************/
2629  /* */
2630  /* Tools */
2631  /* */
2632  /*****************************************************/
2639  protected function doConcatenate() {
2640  $this->doConcatenateCss();
2641  $this->doConcatenateJavaScript();
2642  }
2643 
2649  protected function doConcatenateJavaScript() {
2650  if ($this->concatenateFiles || $this->concatenateJavascript) {
2651  if (!empty($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['jsConcatenateHandler'])) {
2652  // use external concatenation routine
2653  $params = array(
2654  'jsLibs' => &$this->jsLibs,
2655  'jsFiles' => &$this->jsFiles,
2656  'jsFooterFiles' => &$this->jsFooterFiles,
2657  'headerData' => &$this->headerData,
2658  'footerData' => &$this->footerData
2659  );
2660  GeneralUtility::callUserFunction($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['jsConcatenateHandler'], $params, $this);
2661  } else {
2662  $this->jsLibs = $this->getCompressor()->concatenateJsFiles($this->jsLibs);
2663  $this->jsFiles = $this->getCompressor()->concatenateJsFiles($this->jsFiles);
2664  $this->jsFooterFiles = $this->getCompressor()->concatenateJsFiles($this->jsFooterFiles);
2665  }
2666  }
2667  }
2668 
2674  protected function doConcatenateCss() {
2675  if ($this->concatenateFiles || $this->concatenateCss) {
2676  if (!empty($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['cssConcatenateHandler'])) {
2677  // use external concatenation routine
2678  $params = array(
2679  'cssFiles' => &$this->cssFiles,
2680  'cssLibs' => &$this->cssLibs,
2681  'headerData' => &$this->headerData,
2682  'footerData' => &$this->footerData
2683  );
2684  GeneralUtility::callUserFunction($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['cssConcatenateHandler'], $params, $this);
2685  } else {
2686  $cssOptions = array();
2687  if (TYPO3_MODE === 'BE') {
2688  $cssOptions = array('baseDirectories' => $GLOBALS['TBE_TEMPLATE']->getSkinStylesheetDirectories());
2689  }
2690  $this->cssLibs = $this->getCompressor()->concatenateCssFiles($this->cssLibs, $cssOptions);
2691  $this->cssFiles = $this->getCompressor()->concatenateCssFiles($this->cssFiles, $cssOptions);
2692  }
2693  }
2694  }
2695 
2701  protected function doCompress() {
2702  $this->doCompressJavaScript();
2703  $this->doCompressCss();
2704  }
2705 
2711  protected function doCompressCss() {
2712  if ($this->compressCss) {
2713  if (!empty($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['cssCompressHandler'])) {
2714  // Use external compression routine
2715  $params = array(
2716  'cssInline' => &$this->cssInline,
2717  'cssFiles' => &$this->cssFiles,
2718  'cssLibs' => &$this->cssLibs,
2719  'headerData' => &$this->headerData,
2720  'footerData' => &$this->footerData
2721  );
2722  GeneralUtility::callUserFunction($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['cssCompressHandler'], $params, $this);
2723  } else {
2724  $this->cssLibs = $this->getCompressor()->compressCssFiles($this->cssLibs);
2725  $this->cssFiles = $this->getCompressor()->compressCssFiles($this->cssFiles);
2726  }
2727  }
2728  }
2729 
2735  protected function doCompressJavaScript() {
2736  if ($this->compressJavascript) {
2737  if (!empty($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['jsCompressHandler'])) {
2738  // Use external compression routine
2739  $params = array(
2740  'jsInline' => &$this->jsInline,
2741  'jsFooterInline' => &$this->jsFooterInline,
2742  'jsLibs' => &$this->jsLibs,
2743  'jsFiles' => &$this->jsFiles,
2744  'jsFooterFiles' => &$this->jsFooterFiles,
2745  'headerData' => &$this->headerData,
2746  'footerData' => &$this->footerData
2747  );
2748  GeneralUtility::callUserFunction($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['jsCompressHandler'], $params, $this);
2749  } else {
2750  // Traverse the arrays, compress files
2751  if (count($this->jsInline)) {
2752  foreach ($this->jsInline as $name => $properties) {
2753  if ($properties['compress']) {
2754  $error = '';
2755  $this->jsInline[$name]['code'] = GeneralUtility::minifyJavaScript($properties['code'], $error);
2756  if ($error) {
2757  $this->compressError .= 'Error with minify JS Inline Block "' . $name . '": ' . $error . LF;
2758  }
2759  }
2760  }
2761  }
2762  $this->jsLibs = $this->getCompressor()->compressJsFiles($this->jsLibs);
2763  $this->jsFiles = $this->getCompressor()->compressJsFiles($this->jsFiles);
2764  $this->jsFooterFiles = $this->getCompressor()->compressJsFiles($this->jsFooterFiles);
2765  }
2766  }
2767  }
2768 
2774  protected function getCompressor() {
2775  if ($this->compressor === NULL) {
2776  $this->compressor = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\ResourceCompressor');
2777  }
2778  return $this->compressor;
2779  }
2780 
2789  protected function processJsFile($filename) {
2790  switch (TYPO3_MODE) {
2791  case 'FE':
2792  if ($this->compressJavascript) {
2793  $filename = $this->getCompressor()->compressJsFile($filename);
2794  } else {
2795  $filename = GeneralUtility::createVersionNumberedFilename($filename);
2796  }
2797  break;
2798  case 'BE':
2799  if ($this->compressJavascript) {
2800  $filename = $this->getCompressor()->compressJsFile($filename);
2801  }
2802  break;
2803  }
2804  return $filename;
2805  }
2806 
2807  /*****************************************************/
2808  /* */
2809  /* Hooks */
2810  /* */
2811  /*****************************************************/
2817  protected function executePreRenderHook() {
2818  if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_pagerenderer.php']['render-preProcess'])) {
2819  $params = array(
2820  'jsLibs' => &$this->jsLibs,
2821  'jsFooterLibs' => &$this->jsFooterLibs,
2822  'jsFiles' => &$this->jsFiles,
2823  'jsFooterFiles' => &$this->jsFooterFiles,
2824  'cssFiles' => &$this->cssFiles,
2825  'headerData' => &$this->headerData,
2826  'footerData' => &$this->footerData,
2827  'jsInline' => &$this->jsInline,
2828  'jsFooterInline' => &$this->jsFooterInline,
2829  'cssInline' => &$this->cssInline
2830  );
2831  foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_pagerenderer.php']['render-preProcess'] as $hook) {
2832  GeneralUtility::callUserFunction($hook, $params, $this);
2833  }
2834  }
2835  }
2836 
2842  protected function executeRenderPostTransformHook() {
2843  if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_pagerenderer.php']['render-postTransform'])) {
2844  $params = array(
2845  'jsLibs' => &$this->jsLibs,
2846  'jsFooterLibs' => &$this->jsFooterLibs,
2847  'jsFiles' => &$this->jsFiles,
2848  'jsFooterFiles' => &$this->jsFooterFiles,
2849  'cssFiles' => &$this->cssFiles,
2850  'headerData' => &$this->headerData,
2851  'footerData' => &$this->footerData,
2852  'jsInline' => &$this->jsInline,
2853  'jsFooterInline' => &$this->jsFooterInline,
2854  'cssInline' => &$this->cssInline
2855  );
2856  foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_pagerenderer.php']['render-postTransform'] as $hook) {
2857  GeneralUtility::callUserFunction($hook, $params, $this);
2858  }
2859  }
2860  }
2861 
2877  if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_pagerenderer.php']['render-postProcess'])) {
2878  $params = array(
2879  'jsLibs' => &$jsLibs,
2880  'jsFiles' => &$jsFiles,
2881  'jsFooterFiles' => &$jsFooterFiles,
2882  'cssLibs' => &$cssLibs,
2883  'cssFiles' => &$cssFiles,
2884  'headerData' => &$this->headerData,
2885  'footerData' => &$this->footerData,
2886  'jsInline' => &$jsInline,
2887  'cssInline' => &$cssInline,
2888  'xmlPrologAndDocType' => &$this->xmlPrologAndDocType,
2889  'htmlTag' => &$this->htmlTag,
2890  'headTag' => &$this->headTag,
2891  'charSet' => &$this->charSet,
2892  'metaCharsetTag' => &$this->metaCharsetTag,
2893  'shortcutTag' => &$this->shortcutTag,
2894  'inlineComments' => &$this->inlineComments,
2895  'baseUrl' => &$this->baseUrl,
2896  'baseUrlTag' => &$this->baseUrlTag,
2897  'favIcon' => &$this->favIcon,
2898  'iconMimeType' => &$this->iconMimeType,
2899  'titleTag' => &$this->titleTag,
2900  'title' => &$this->title,
2901  'metaTags' => &$this->metaTags,
2902  'jsFooterInline' => &$jsFooterInline,
2903  'jsFooterLibs' => &$jsFooterLibs,
2904  'bodyContent' => &$this->bodyContent
2905  );
2906  foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_pagerenderer.php']['render-postProcess'] as $hook) {
2907  GeneralUtility::callUserFunction($hook, $params, $this);
2908  }
2909  }
2910  }
2911 
2912 }
static minifyJavaScript($script, &$error='')
static mergeRecursiveWithOverrule(array &$original, array $overrule, $addKeys=TRUE, $includeEmptyValues=TRUE, $enableUnsetFeature=TRUE)
loadExtJS($css=TRUE, $theme=TRUE, $adapter='')
renderJavaScriptAndCssForProcessingOfUncachedContentObjects($cachedPageContent, $substituteHash)
addExtOnReadyCode($block, $forceOnTop=FALSE)
renderPageWithUncachedObjects($substituteHash)
addInlineSettingArray($namespace, array $array)
static getAjaxUrl($ajaxIdentifier, array $urlParameters=array(), $backPathOverride=FALSE, $returnAbsoluteUrl=FALSE)
getPreparedMarkerArrayForPageWithUncachedObjects($substituteHash)
addJsLibrary($name, $file, $type='text/javascript', $compress=FALSE, $forceOnTop=FALSE, $allWrap='', $excludeFromConcatenation=FALSE, $splitChar='|')
renderJqueryScriptTag($version, $source, $namespace)
addJsInlineCode($name, $block, $compress=TRUE, $forceOnTop=FALSE)
readLLfile($fileRef, $errorMode=0)
setXmlPrologAndDocType($xmlPrologAndDocType)
const TYPO3_MODE
Definition: init.php:40
addCssInlineBlock($name, $block, $compress=FALSE, $forceOnTop=FALSE)
addInlineSetting($namespace, $key, $value)
render($part=self::PART_COMPLETE)
$formprotection
Definition: mod.php:24
__construct($templateFile='', $backPath=NULL)
static trimExplode($delim, $string, $removeEmptyValues=FALSE, $limit=0)
static callUserFunction($funcName, &$params, &$ref, $checkPrefix='', $errorMode=0)
getPreparedMarkerArray($jsLibs, $jsFiles, $jsFooterFiles, $cssLibs, $cssFiles, $jsInline, $cssInline, $jsFooterInline, $jsFooterLibs, $metaTags)
static createVersionNumberedFilename($file, $forceQueryString=FALSE)
static getUrl($url, $includeHeader=0, $requestHeaders=FALSE, &$report=NULL)
includeLanguageFileForInline($fileRef, $selectionPrefix='', $stripFromSelectionName='', $errorMode=0)
addJsFile($file, $type='text/javascript', $compress=TRUE, $forceOnTop=FALSE, $allWrap='', $excludeFromConcatenation=FALSE, $splitChar='|')
addInlineLanguageLabelFile($fileRef, $selectionPrefix='', $stripFromSelectionName='', $errorMode=0)
addJsFooterFile($file, $type='text/javascript', $compress=TRUE, $forceOnTop=FALSE, $allWrap='', $excludeFromConcatenation=FALSE, $splitChar='|')
loadJquery($version=NULL, $source=NULL, $namespace=self::JQUERY_NAMESPACE_DEFAULT)
addJsFooterInlineCode($name, $block, $compress=TRUE, $forceOnTop=FALSE)
addJsFooterLibrary($name, $file, $type='text/javascript', $compress=FALSE, $forceOnTop=FALSE, $allWrap='', $excludeFromConcatenation=FALSE, $splitChar='|')
static getRelativePath($sourcePath, $targetPath)
Definition: PathUtility.php:71
if(!defined('TYPO3_MODE')) $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauth.php']['logoff_pre_processing'][]
static getFileAbsFileName($filename, $onlyRelative=TRUE, $relToTYPO3_mainDir=FALSE)
addCssFile($file, $rel='stylesheet', $media='all', $title='', $compress=TRUE, $forceOnTop=FALSE, $allWrap='', $excludeFromConcatenation=FALSE, $splitChar='|')
addCssLibrary($file, $rel='stylesheet', $media='all', $title='', $compress=TRUE, $forceOnTop=FALSE, $allWrap='', $excludeFromConcatenation=FALSE, $splitChar='|')
executePostRenderHook(&$jsLibs, &$jsFiles, &$jsFooterFiles, &$cssLibs, &$cssFiles, &$jsInline, &$cssInline, &$jsFooterInline, &$jsFooterLibs)
addRequireJsConfiguration(array $configuration)
static wrapJS($string, $linebreak=TRUE)