2 namespace TYPO3\CMS\Core\Page;
202 protected $metaCharsetTag =
'<meta http-equiv="Content-Type" content="text/html; charset=|" />';
227 protected $shortcutTag =
'<link rel="shortcut icon" href="%1$s"%2$s />';
276 protected $extJsPath =
'sysext/core/Resources/Public/JavaScript/Contrib/extjs/';
283 protected $jQueryPath =
'sysext/core/Resources/Public/JavaScript/Contrib/jquery/';
311 self::JQUERY_VERSION_LATEST
320 'google' =>
'https://ajax.googleapis.com/ajax/libs/jquery/%1$s/jquery%2$s.js',
321 'msn' =>
'https://ajax.aspnetcdn.com/ajax/jQuery/jquery-%1$s%2$s.js',
322 'jquery' =>
'https://code.jquery.com/jquery-%1$s%2$s.js',
323 'cloudflare' =>
'https://cdnjs.cloudflare.com/ajax/libs/jquery/%1$s/jquery%2$s.js'
422 $this->inlineJavascriptWrap = array(
423 '<script type="text/javascript">' . LF .
'/*<![CDATA[*/' . LF,
424 '/*]]>*/' . LF .
'</script>' . LF
426 $this->inlineCssWrap = array(
427 '<style type="text/css">' . LF .
'/*<![CDATA[*/' . LF .
'<!-- ' . LF,
428 '-->' . LF .
'/*]]>*/' . LF .
'</style>' . LF
439 $this->templateFile =
'EXT:core/Resources/Private/Templates/PageRenderer.html';
440 $this->jsFiles = array();
441 $this->jsFooterFiles = array();
442 $this->jsInline = array();
443 $this->jsFooterInline = array();
444 $this->jsLibs = array();
445 $this->cssFiles = array();
446 $this->cssInline = array();
447 $this->metaTags = array();
448 $this->inlineComments = array();
449 $this->headerData = array();
450 $this->footerData = array();
451 $this->extOnReadyCode = array();
452 $this->jQueryVersions = array();
480 $this->renderXhtml = $enable;
514 $this->languageDependencies = array();
517 if (in_array($this->lang, $this->locales->getLocales())) {
519 foreach ($this->locales->getLocaleDependencies($this->lang) as $language) {
520 $this->languageDependencies[] = $language;
599 $this->templateFile = $file;
621 $this->bodyContent = $content;
632 $this->requireJsPath = $path;
643 $this->extJsPath = $path;
659 $this->moveJsFromHeaderToFooter =
true;
669 $this->moveJsFromHeaderToFooter =
false;
679 $this->compressJavascript =
true;
689 $this->compressJavascript =
false;
699 $this->compressCss =
true;
709 $this->compressCss =
false;
719 $this->concatenateFiles =
true;
729 $this->concatenateFiles =
false;
739 $this->concatenateJavascript =
true;
749 $this->concatenateJavascript =
false;
759 $this->concatenateCss =
true;
769 $this->concatenateCss =
false;
779 $this->removeLineBreaksFromTemplate =
true;
789 $this->removeLineBreaksFromTemplate =
false;
800 $this->compressJavascript =
false;
801 $this->compressCss =
false;
802 $this->concatenateFiles =
false;
803 $this->removeLineBreaksFromTemplate =
false;
805 $this->enableJqueryDebug =
true;
1048 if (!in_array($meta, $this->metaTags)) {
1049 $this->metaTags[] = $meta;
1061 if (!in_array($comment, $this->inlineComments)) {
1062 $this->inlineComments[] = $comment;
1074 if (!in_array($data, $this->headerData)) {
1075 $this->headerData[] = $data;
1087 if (!in_array($data, $this->footerData)) {
1088 $this->footerData[] = $data;
1107 public function addJsLibrary($name, $file, $type =
'text/javascript', $compress =
false, $forceOnTop =
false, $allWrap =
'', $excludeFromConcatenation =
false, $splitChar =
'|', $async =
false, $integrity =
'')
1110 $type =
'text/javascript';
1112 if (!in_array(strtolower($name), $this->jsLibs)) {
1113 $this->jsLibs[strtolower($name)] = array(
1116 'section' => self::PART_HEADER,
1117 'compress' => $compress,
1118 'forceOnTop' => $forceOnTop,
1119 'allWrap' => $allWrap,
1120 'excludeFromConcatenation' => $excludeFromConcatenation,
1121 'splitChar' => $splitChar,
1123 'integrity' => $integrity,
1143 public function addJsFooterLibrary($name, $file, $type =
'text/javascript', $compress =
false, $forceOnTop =
false, $allWrap =
'', $excludeFromConcatenation =
false, $splitChar =
'|', $async =
false, $integrity =
'')
1146 $type =
'text/javascript';
1148 if (!in_array(strtolower($name), $this->jsLibs)) {
1149 $this->jsLibs[strtolower($name)] = array(
1152 'section' => self::PART_FOOTER,
1153 'compress' => $compress,
1154 'forceOnTop' => $forceOnTop,
1155 'allWrap' => $allWrap,
1156 'excludeFromConcatenation' => $excludeFromConcatenation,
1157 'splitChar' => $splitChar,
1159 'integrity' => $integrity,
1178 public function addJsFile($file, $type =
'text/javascript', $compress =
true, $forceOnTop =
false, $allWrap =
'', $excludeFromConcatenation =
false, $splitChar =
'|', $async =
false, $integrity =
'')
1181 $type =
'text/javascript';
1183 if (!isset($this->jsFiles[$file])) {
1184 $this->jsFiles[$file] = array(
1187 'section' => self::PART_HEADER,
1188 'compress' => $compress,
1189 'forceOnTop' => $forceOnTop,
1190 'allWrap' => $allWrap,
1191 'excludeFromConcatenation' => $excludeFromConcatenation,
1192 'splitChar' => $splitChar,
1194 'integrity' => $integrity,
1213 public function addJsFooterFile($file, $type =
'text/javascript', $compress =
true, $forceOnTop =
false, $allWrap =
'', $excludeFromConcatenation =
false, $splitChar =
'|', $async =
false, $integrity =
'')
1216 $type =
'text/javascript';
1218 if (!isset($this->jsFiles[$file])) {
1219 $this->jsFiles[$file] = array(
1222 'section' => self::PART_FOOTER,
1223 'compress' => $compress,
1224 'forceOnTop' => $forceOnTop,
1225 'allWrap' => $allWrap,
1226 'excludeFromConcatenation' => $excludeFromConcatenation,
1227 'splitChar' => $splitChar,
1229 'integrity' => $integrity,
1245 if (!isset($this->jsInline[$name]) && !empty($block)) {
1246 $this->jsInline[$name] = array(
1247 'code' => $block . LF,
1248 'section' => self::PART_HEADER,
1249 'compress' => $compress,
1250 'forceOnTop' => $forceOnTop
1266 if (!isset($this->jsInline[$name]) && !empty($block)) {
1267 $this->jsInline[$name] = array(
1268 'code' => $block . LF,
1269 'section' => self::PART_FOOTER,
1270 'compress' => $compress,
1271 'forceOnTop' => $forceOnTop
1285 if (!in_array($block, $this->extOnReadyCode)) {
1287 array_unshift($this->extOnReadyCode, $block);
1289 $this->extOnReadyCode[] = $block;
1300 public function addExtDirectCode(array $filterNamespaces = array())
1302 if ($this->extDirectCodeAdded) {
1305 $this->extDirectCodeAdded =
true;
1306 if (empty($filterNamespaces)) {
1307 $filterNamespaces = array(
'TYPO3');
1312 'sysext/backend/Resources/Public/JavaScript/flashmessage_compatibility.js'));
1315 if (TYPO3_MODE ===
'FE') {
1322 'extDirect_timeoutHeader' => $this->
getLanguageService()->sL(
'LLL:EXT:lang/locallang_misc.xlf:extDirect_timeoutHeader'),
1323 'extDirect_timeoutMessage' => $this->
getLanguageService()->sL(
'LLL:EXT:lang/locallang_misc.xlf:extDirect_timeoutMessage')
1327 $token = ($api =
'');
1328 if (TYPO3_MODE ===
'BE') {
1329 $formprotection = \TYPO3\CMS\Core\FormProtection\FormProtectionFactory::get();
1330 $token = $formprotection->generateToken(
'extDirect');
1337 $api = $extDirect->getApiPhp($filterNamespaces);
1345 TYPO3.ExtDirectToken = "' . $token .
'";
1346 for (var api in Ext.app.ExtDirectAPI) {
1347 var provider = Ext.Direct.addProvider(Ext.app.ExtDirectAPI[api]);
1348 provider.on("beforecall", function(provider, transaction, meta) {
1349 if (transaction.data) {
1350 transaction.data[transaction.data.length] = TYPO3.ExtDirectToken;
1352 transaction.data = [TYPO3.ExtDirectToken];
1356 provider.on("call", function(provider, transaction, meta) {
1357 if (transaction.isForm) {
1358 transaction.params.securityToken = TYPO3.ExtDirectToken;
1364 var extDirectDebug = function(message, header, group) {
1365 var DebugConsole = null;
1367 if (top && top.TYPO3 && typeof top.TYPO3.DebugConsole === "object") {
1368 DebugConsole = top.TYPO3.DebugConsole;
1369 } else if (typeof TYPO3 === "object" && typeof TYPO3.DebugConsole === "object") {
1370 DebugConsole = TYPO3.DebugConsole;
1373 if (DebugConsole !== null) {
1374 DebugConsole.add(message, header, group);
1375 } else if (typeof console === "object") {
1376 console.log(message);
1378 document.write(message);
1382 Ext.Direct.on("exception", function(event) {
1383 if (event.code === Ext.Direct.exceptions.TRANSPORT && !event.where) {
1384 top.TYPO3.Notification.error(
1385 TYPO3.l10n.localize("extDirect_timeoutHeader"),
1386 TYPO3.l10n.localize("extDirect_timeoutMessage")
1390 if (event.code === "parse") {
1392 "<p>" + event.xhr.responseText + "<\\/p>",
1394 "ExtDirect - Exception"
1396 } else if (event.code === "router") {
1397 top.TYPO3.Notification.error(
1401 } else if (event.where) {
1402 backtrace = "<p style=\\"margin-top: 20px;\\">" +
1403 "<strong>Backtrace:<\\/strong><br \\/>" +
1404 event.where.replace(/#/g, "<br \\/>#") +
1407 "<p>" + event.message + "<\\/p>" + backtrace,
1409 "ExtDirect - Exception"
1417 Ext.Direct.on("event", function(event, provider) {
1418 if (typeof event.debug !== "undefined" && event.debug !== "") {
1419 extDirectDebug(event.debug, event.method, "ExtDirect - Debug");
1439 public function addCssFile($file, $rel =
'stylesheet', $media =
'all',
$title =
'', $compress =
true, $forceOnTop =
false, $allWrap =
'', $excludeFromConcatenation =
false, $splitChar =
'|')
1441 if (!isset($this->cssFiles[$file])) {
1442 $this->cssFiles[$file] = array(
1447 'compress' => $compress,
1448 'forceOnTop' => $forceOnTop,
1449 'allWrap' => $allWrap,
1450 'excludeFromConcatenation' => $excludeFromConcatenation,
1451 'splitChar' => $splitChar
1470 public function addCssLibrary($file, $rel =
'stylesheet', $media =
'all',
$title =
'', $compress =
true, $forceOnTop =
false, $allWrap =
'', $excludeFromConcatenation =
false, $splitChar =
'|')
1472 if (!isset($this->cssLibs[$file])) {
1473 $this->cssLibs[$file] = array(
1478 'compress' => $compress,
1479 'forceOnTop' => $forceOnTop,
1480 'allWrap' => $allWrap,
1481 'excludeFromConcatenation' => $excludeFromConcatenation,
1482 'splitChar' => $splitChar
1498 if (!isset($this->cssInline[$name]) && !empty($block)) {
1499 $this->cssInline[$name] = array(
1501 'compress' => $compress,
1502 'forceOnTop' => $forceOnTop
1516 public function loadJquery($version = null, $source = null, $namespace = self::JQUERY_NAMESPACE_DEFAULT)
1519 if ($version === null || $version ===
'latest') {
1520 $version = self::JQUERY_VERSION_LATEST;
1523 if ($source === null) {
1526 if ($source ===
'local' && !in_array($version, $this->availableLocalJqueryVersions)) {
1527 throw new \UnexpectedValueException(
'The requested jQuery version is not available in the local filesystem.', 1341505305);
1529 if (!preg_match(
'/^[a-zA-Z0-9]+$/', $namespace)) {
1530 throw new \UnexpectedValueException(
'The requested namespace contains non alphanumeric characters.', 1341571604);
1532 $this->jQueryVersions[$namespace] = array(
1533 'version' => $version,
1550 if (empty($this->requireJsConfig)) {
1553 $this->requireJsConfig[
'urlArgs'] =
'bust=' .
$GLOBALS[
'EXEC_TIME'];
1558 $this->requireJsConfig[
'paths'] = array(
1559 'jquery-ui' => $this->backPath .
'sysext/core/Resources/Public/JavaScript/Contrib/jquery-ui',
1560 'datatables' => $this->backPath .
'sysext/core/Resources/Public/JavaScript/Contrib/jquery.dataTables',
1561 'nprogress' => $this->backPath .
'sysext/core/Resources/Public/JavaScript/Contrib/nprogress',
1562 'moment' => $this->backPath .
'sysext/core/Resources/Public/JavaScript/Contrib/moment',
1563 'cropper' => $this->backPath .
'sysext/core/Resources/Public/JavaScript/Contrib/cropper.min',
1564 'imagesloaded' => $this->backPath .
'sysext/core/Resources/Public/JavaScript/Contrib/imagesloaded.pkgd.min',
1565 'bootstrap' => $this->backPath .
'sysext/core/Resources/Public/JavaScript/Contrib/bootstrap/bootstrap',
1566 'twbs/bootstrap-datetimepicker' => $this->backPath .
'sysext/core/Resources/Public/JavaScript/Contrib/bootstrap-datetimepicker',
1567 'autosize' => $this->backPath .
'sysext/core/Resources/Public/JavaScript/Contrib/autosize',
1568 'taboverride' => $this->backPath .
'sysext/core/Resources/Public/JavaScript/Contrib/taboverride.min',
1569 'twbs/bootstrap-slider' => $this->backPath .
'sysext/core/Resources/Public/JavaScript/Contrib/bootstrap-slider.min',
1570 'jquery/autocomplete' => $this->backPath .
'sysext/core/Resources/Public/JavaScript/Contrib/jquery.autocomplete',
1573 $loadedExtensions = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getLoadedExtensionListArray();
1574 foreach ($loadedExtensions as $packageName) {
1575 $fullJsPath =
'EXT:' . $packageName .
'/Resources/Public/JavaScript/';
1577 $fullJsPath = \TYPO3\CMS\Core\Utility\PathUtility::getRelativePath(PATH_typo3, $fullJsPath);
1578 $fullJsPath = rtrim($fullJsPath,
'/');
1585 if (is_array(
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
'RequireJS'][
'postInitializationModules'])) {
1586 $this->
addInlineSettingArray(
'RequireJS.PostInitializationModules',
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
'RequireJS'][
'postInitializationModules']);
1590 $this->addRequireJs =
true;
1608 \TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($this->requireJsConfig, $configuration);
1630 $inlineCodeKey = $mainModuleName;
1635 $javaScriptCode =
'require(["' . $mainModuleName .
'"]';
1636 if ($callBackFunction !== null) {
1637 $inlineCodeKey .= sha1($callBackFunction);
1638 $javaScriptCode .=
', ' . $callBackFunction;
1640 $javaScriptCode .=
');';
1641 $this->
addJsInlineCode(
'RequireJS-Module-' . $inlineCodeKey, $javaScriptCode);
1654 $this->addExtJS =
true;
1655 $this->extJStheme = $theme;
1656 $this->extJScss = $css;
1680 $this->inlineLanguageLabels[$key] = $value;
1695 if ($parseWithLanguageService ===
true) {
1696 foreach ($array as $key => $value) {
1697 if (TYPO3_MODE ===
'FE') {
1705 $this->inlineLanguageLabels = array_merge($this->inlineLanguageLabels, $array);
1719 $index = md5($fileRef . $selectionPrefix . $stripFromSelectionName);
1720 if ($fileRef && !isset($this->inlineLanguageLabelFiles[$index])) {
1721 $this->inlineLanguageLabelFiles[$index] = array(
1722 'fileRef' => $fileRef,
1723 'selectionPrefix' => $selectionPrefix,
1724 'stripFromSelectionName' => $stripFromSelectionName,
1725 'errorMode' => $errorMode
1743 if (strpos($namespace,
'.')) {
1744 $parts = explode(
'.', $namespace);
1746 foreach ($parts as $part) {
1751 $this->inlineSettings[$namespace][$key] = $value;
1754 $this->inlineSettings[$key] = $value;
1771 if (strpos($namespace,
'.')) {
1772 $parts = explode(
'.', $namespace);
1774 foreach ($parts as $part) {
1777 $a = array_merge((array)$a, $array);
1779 $this->inlineSettings[$namespace] = array_merge((array)$this->inlineSettings[$namespace], $array);
1782 $this->inlineSettings = array_merge($this->inlineSettings, $array);
1794 $this->bodyContent .= $content;
1808 public function render($part = self::PART_COMPLETE)
1812 $metaTags = implode(LF, $this->metaTags);
1821 return trim($templateService->substituteMarkerArray($template, $markerArray,
'###|###'));
1837 return trim($templateService->substituteMarkerArray($template, $markerArray,
'###|###'));
1853 $title = $this->title ? str_replace(
'|', htmlspecialchars($this->title), $this->titleTag) :
'';
1854 $markerArray = array(
1855 '<!-- ###TITLE' . $substituteHash .
'### -->' =>
$title,
1856 '<!-- ###CSS_LIBS' . $substituteHash .
'### -->' =>
$cssLibs,
1857 '<!-- ###CSS_INCLUDE' . $substituteHash .
'### -->' =>
$cssFiles,
1858 '<!-- ###CSS_INLINE' . $substituteHash .
'### -->' =>
$cssInline,
1859 '<!-- ###JS_INLINE' . $substituteHash .
'### -->' =>
$jsInline,
1860 '<!-- ###JS_INCLUDE' . $substituteHash .
'### -->' =>
$jsFiles,
1861 '<!-- ###JS_LIBS' . $substituteHash .
'### -->' =>
$jsLibs,
1862 '<!-- ###HEADERDATA' . $substituteHash .
'### -->' => implode(LF, $this->headerData),
1863 '<!-- ###FOOTERDATA' . $substituteHash .
'### -->' => implode(LF, $this->footerData),
1864 '<!-- ###JS_LIBS_FOOTER' . $substituteHash .
'### -->' =>
$jsFooterLibs,
1865 '<!-- ###JS_INCLUDE_FOOTER' . $substituteHash .
'### -->' =>
$jsFooterFiles,
1866 '<!-- ###JS_INLINE_FOOTER' . $substituteHash .
'### -->' =>
$jsFooterInline
1868 foreach ($markerArray as $placeHolder => $content) {
1869 $cachedPageContent = str_replace($placeHolder, $content, $cachedPageContent);
1872 return $cachedPageContent;
1885 $this->endingSlash =
' /';
1887 $this->metaCharsetTag = str_replace(
' />',
'>', $this->metaCharsetTag);
1888 $this->baseUrlTag = str_replace(
' />',
'>', $this->baseUrlTag);
1889 $this->shortcutTag = str_replace(
' />',
'>', $this->shortcutTag);
1890 $this->endingSlash =
'';
1903 if ($this->concatenateFiles || $this->concatenateJavascript || $this->concatenateCss) {
1907 if ($this->compressCss || $this->compressJavascript) {
1919 if ($this->moveJsFromHeaderToFooter) {
1948 $markerArray = array(
1949 'XMLPROLOG_DOCTYPE' => $this->xmlPrologAndDocType,
1950 'HTMLTAG' => $this->htmlTag,
1951 'HEADTAG' => $this->headTag,
1952 'METACHARSET' => $this->charSet ? str_replace(
'|', htmlspecialchars($this->charSet), $this->metaCharsetTag) :
'',
1953 'INLINECOMMENT' => $this->inlineComments ? LF . LF .
'<!-- ' . LF . implode(LF, $this->inlineComments) .
'-->' . LF . LF :
'',
1954 'BASEURL' => $this->baseUrl ? str_replace(
'|', $this->baseUrl, $this->baseUrlTag) :
'',
1955 'SHORTCUT' => $this->favIcon ? sprintf($this->shortcutTag, htmlspecialchars($this->favIcon), $this->iconMimeType) :
'',
1962 'TITLE' => $this->title ? str_replace(
'|', htmlspecialchars($this->title), $this->titleTag) :
'',
1964 'HEADERDATA' => $this->headerData ? implode(LF, $this->headerData) :
'',
1965 'FOOTERDATA' => $this->footerData ? implode(LF, $this->footerData) :
'',
1969 'BODY' => $this->bodyContent
1971 $markerArray = array_map(
'trim', $markerArray);
1972 return $markerArray;
1983 $markerArray = array(
1984 'XMLPROLOG_DOCTYPE' => $this->xmlPrologAndDocType,
1985 'HTMLTAG' => $this->htmlTag,
1986 'HEADTAG' => $this->headTag,
1987 'METACHARSET' => $this->charSet ? str_replace(
'|', htmlspecialchars($this->charSet), $this->metaCharsetTag) :
'',
1988 'INLINECOMMENT' => $this->inlineComments ? LF . LF .
'<!-- ' . LF . implode(LF, $this->inlineComments) .
'-->' . LF . LF :
'',
1989 'BASEURL' => $this->baseUrl ? str_replace(
'|', $this->baseUrl, $this->baseUrlTag) :
'',
1990 'SHORTCUT' => $this->favIcon ? sprintf($this->shortcutTag, htmlspecialchars($this->favIcon), $this->iconMimeType) :
'',
1991 'META' => implode(LF, $this->metaTags),
1992 'BODY' => $this->bodyContent,
1993 'TITLE' =>
'<!-- ###TITLE' . $substituteHash .
'### -->',
1994 'CSS_LIBS' =>
'<!-- ###CSS_LIBS' . $substituteHash .
'### -->',
1995 'CSS_INCLUDE' =>
'<!-- ###CSS_INCLUDE' . $substituteHash .
'### -->',
1996 'CSS_INLINE' =>
'<!-- ###CSS_INLINE' . $substituteHash .
'### -->',
1997 'JS_INLINE' =>
'<!-- ###JS_INLINE' . $substituteHash .
'### -->',
1998 'JS_INCLUDE' =>
'<!-- ###JS_INCLUDE' . $substituteHash .
'### -->',
1999 'JS_LIBS' =>
'<!-- ###JS_LIBS' . $substituteHash .
'### -->',
2000 'HEADERDATA' =>
'<!-- ###HEADERDATA' . $substituteHash .
'### -->',
2001 'FOOTERDATA' =>
'<!-- ###FOOTERDATA' . $substituteHash .
'### -->',
2002 'JS_LIBS_FOOTER' =>
'<!-- ###JS_LIBS_FOOTER' . $substituteHash .
'### -->',
2003 'JS_INCLUDE_FOOTER' =>
'<!-- ###JS_INCLUDE_FOOTER' . $substituteHash .
'### -->',
2004 'JS_INLINE_FOOTER' =>
'<!-- ###JS_INLINE_FOOTER' . $substituteHash .
'### -->'
2006 $markerArray = array_map(
'trim', $markerArray);
2007 return $markerArray;
2020 if ($this->removeLineBreaksFromTemplate) {
2021 $template = strtr($template, array(LF =>
'', CR =>
''));
2023 if ($part !== self::PART_COMPLETE) {
2024 $templatePart = explode(
'###BODY###', $template);
2025 $template = $templatePart[$part - 1];
2041 if ($this->addRequireJs) {
2045 $out .=
'<script src="' . $this->
processJsFile(($this->backPath . $this->requireJsPath .
'require.js')) .
'" type="text/javascript"></script>' . LF;
2049 if (!empty($this->jQueryVersions)) {
2050 foreach ($this->jQueryVersions as $namespace => $jQueryVersion) {
2051 $out .= $this->
renderJqueryScriptTag($jQueryVersion[
'version'], $jQueryVersion[
'source'], $namespace);
2055 if ($this->addExtJS) {
2057 $out .=
'<script src="' . $this->
processJsFile(($this->backPath . $this->extJsPath .
'adapter/ext-base' . ($this->
enableExtJsDebug ?
'-debug' :
'') .
'.js')) .
'" type="text/javascript"></script>' . LF;
2058 $out .=
'<script src="' . $this->
processJsFile(($this->backPath . $this->extJsPath .
'ext-all' . ($this->
enableExtJsDebug ?
'-debug' :
'') .
'.js')) .
'" type="text/javascript"></script>' . LF;
2061 $localeMap = $this->locales->getIsoMapping();
2062 $localeMap[
''] =
'en';
2063 $localeMap[
'default'] =
'en';
2065 $localeMap[
'gr'] =
'el_GR';
2067 $localeMap[
'no'] =
'no_BO';
2069 $localeMap[
'se'] =
'se_SV';
2072 $extJsLocaleFile = $this->extJsPath .
'locale/ext-lang-' . $extJsLang .
'.js';
2073 if (file_exists(PATH_typo3 . $extJsLocaleFile)) {
2074 $out .=
'<script src="' . $this->
processJsFile(($this->backPath . $extJsLocaleFile)) .
'" type="text/javascript" charset="utf-8"></script>' . LF;
2077 unset($this->jsFiles[$this->backPath . $this->extJsPath .
'ext-all.js'], $this->jsFiles[$this->backPath . $this->extJsPath .
'ext-all-debug.js']);
2080 if (TYPO3_MODE ===
'BE') {
2081 $this->addAjaxUrlsToInlineSettings();
2083 $inlineSettings = $this->inlineLanguageLabels ?
'TYPO3.lang = ' . json_encode($this->inlineLanguageLabels) .
';' :
'';
2084 $inlineSettings .= $this->inlineSettings ?
'TYPO3.settings = ' . json_encode($this->inlineSettings) .
';' :
'';
2085 if ($this->addExtJS) {
2088 if (!empty($this->extOnReadyCode)) {
2089 foreach ($this->extOnReadyCode as $block) {
2093 $out .= $this->inlineJavascriptWrap[0] .
'
2098 .
'Ext.onReady(function() {'
2101 . $this->inlineJavascriptWrap[1];
2102 $this->extOnReadyCode = array();
2104 if (TYPO3_MODE ===
'BE') {
2105 $out .=
'<script src="' . $this->
processJsFile(($this->backPath .
'sysext/lang/Resources/Public/JavaScript/Typo3Lang.js')) .
'" type="text/javascript" charset="utf-8"></script>' . LF;
2107 if ($this->extJScss) {
2108 if (isset(
$GLOBALS[
'TBE_STYLES'][
'extJS'][
'all'])) {
2109 $this->
addCssLibrary($this->backPath .
$GLOBALS[
'TBE_STYLES'][
'extJS'][
'all'],
'stylesheet',
'all',
'',
true);
2111 $this->
addCssLibrary($this->backPath . $this->extJsPath .
'resources/css/ext-all-notheme.css',
'stylesheet',
'all',
'',
true);
2114 if ($this->extJStheme) {
2115 if (isset(
$GLOBALS[
'TBE_STYLES'][
'extJS'][
'theme'])) {
2116 $this->
addCssLibrary($this->backPath .
$GLOBALS[
'TBE_STYLES'][
'extJS'][
'theme'],
'stylesheet',
'all',
'',
true);
2118 $this->
addCssLibrary($this->backPath . $this->extJsPath .
'resources/css/xtheme-blue.css',
'stylesheet',
'all',
'',
true);
2126 $out .= $this->inlineJavascriptWrap[0] .
$inlineSettings . $this->inlineJavascriptWrap[1];
2128 if (TYPO3_MODE ===
'BE' && !empty($this->jQueryVersions)) {
2141 if (!empty($this->inlineLanguageLabelFiles)) {
2142 foreach ($this->inlineLanguageLabelFiles as $languageLabelFile) {
2143 $this->
includeLanguageFileForInline($languageLabelFile[
'fileRef'], $languageLabelFile[
'selectionPrefix'], $languageLabelFile[
'stripFromSelectionName'], $languageLabelFile[
'errorMode']);
2146 $this->inlineLanguageLabelFiles = array();
2148 if (TYPO3_MODE ===
'FE' && $this->
getCharSet() !==
'utf-8') {
2149 if ($this->inlineLanguageLabels) {
2150 $this->csConvObj->convArray($this->inlineLanguageLabels, $this->
getCharSet(),
'utf-8');
2152 if ($this->inlineSettings) {
2153 $this->csConvObj->convArray($this->inlineSettings, $this->
getCharSet(),
'utf-8');
2161 protected function addAjaxUrlsToInlineSettings()
2163 $ajaxUrls = array();
2164 foreach (
$GLOBALS[
'TYPO3_CONF_VARS'][
'BE'][
'AJAX'] as $ajaxHandler => $_) {
2165 $ajaxUrls[$ajaxHandler] = BackendUtility::getAjaxUrl($ajaxHandler);
2173 $routes = $router->getRoutes();
2174 foreach ($routes as $routeIdentifier => $route) {
2175 if ($route->getOption(
'ajax')) {
2176 $uri = (string)$uriBuilder->buildUriFromRoute($routeIdentifier);
2178 $routeIdentifier = str_replace(
'ajax_',
'', $routeIdentifier);
2179 $ajaxUrls[$routeIdentifier] = $uri;
2183 $this->inlineSettings[
'ajaxUrls'] = $ajaxUrls;
2197 case isset($this->jQueryCdnUrls[$source]):
2198 if ($this->enableJqueryDebug) {
2201 $minifyPart =
'.min';
2203 $jQueryFileName = sprintf($this->jQueryCdnUrls[$source], $version, $minifyPart);
2205 case $source ===
'local':
2206 $jQueryFileName = $this->backPath . $this->jQueryPath .
'jquery-' . rawurlencode($version);
2207 if ($this->enableJqueryDebug) {
2208 $jQueryFileName .=
'.js';
2210 $jQueryFileName .=
'.min.js';
2214 $jQueryFileName = $source;
2217 $scriptTag =
'<script src="' . htmlspecialchars($jQueryFileName) .
'" type="text/javascript"></script>' . LF;
2219 switch ($namespace) {
2220 case self::JQUERY_NAMESPACE_DEFAULT_NOCONFLICT:
2223 case self::JQUERY_NAMESPACE_NONE:
2225 case self::JQUERY_NAMESPACE_DEFAULT:
2228 $scriptTag .=
GeneralUtility::wrapJS(
'var TYPO3 = TYPO3 || {}; TYPO3.' . $namespace .
' = jQuery.noConflict(true);') . LF;
2241 if (!empty($this->cssLibs)) {
2242 foreach ($this->cssLibs as $file => $properties) {
2245 $tag =
'<link rel="' . htmlspecialchars($properties[
'rel'])
2246 .
'" type="text/css" href="' . htmlspecialchars($file)
2247 .
'" media="' . htmlspecialchars($properties[
'media']) .
'"'
2248 . ($properties[
'title'] ?
' title="' . htmlspecialchars($properties[
'title']) .
'"' :
'')
2249 . $this->endingSlash .
'>';
2250 if ($properties[
'allWrap']) {
2251 $wrapArr = explode($properties[
'splitChar'] ?:
'|', $properties[
'allWrap'], 2);
2252 $tag = $wrapArr[0] . $tag . $wrapArr[1];
2255 if ($properties[
'forceOnTop']) {
2273 if (!empty($this->cssFiles)) {
2274 foreach ($this->cssFiles as $file => $properties) {
2277 $tag =
'<link rel="' . htmlspecialchars($properties[
'rel'])
2278 .
'" type="text/css" href="' . htmlspecialchars($file)
2279 .
'" media="' . htmlspecialchars($properties[
'media']) .
'"'
2280 . ($properties[
'title'] ?
' title="' . htmlspecialchars($properties[
'title']) .
'"' :
'')
2281 . $this->endingSlash .
'>';
2282 if ($properties[
'allWrap']) {
2283 $wrapArr = explode($properties[
'splitChar'] ?:
'|', $properties[
'allWrap'], 2);
2284 $tag = $wrapArr[0] . $tag . $wrapArr[1];
2287 if ($properties[
'forceOnTop']) {
2305 if (!empty($this->cssInline)) {
2306 foreach ($this->cssInline as $name => $properties) {
2307 $cssCode =
'/*' . htmlspecialchars($name) .
'*/' . LF . $properties[
'code'] . LF;
2308 if ($properties[
'forceOnTop']) {
2328 if (!empty($this->jsLibs)) {
2329 foreach ($this->jsLibs as $properties) {
2332 $async = ($properties[
'async']) ?
' async="async"' :
'';
2333 $integrity = ($properties[
'integrity']) ?
' integrity="' . htmlspecialchars($properties[
'integrity']) .
'"' :
'';
2334 $tag =
'<script src="' . htmlspecialchars($properties[
'file']) .
'" type="' . htmlspecialchars($properties[
'type']) .
'"' . $async . $integrity .
'></script>';
2335 if ($properties[
'allWrap']) {
2336 $wrapArr = explode($properties[
'splitChar'] ?:
'|', $properties[
'allWrap'], 2);
2337 $tag = $wrapArr[0] . $tag . $wrapArr[1];
2340 if ($properties[
'forceOnTop']) {
2341 if ($properties[
'section'] === self::PART_HEADER) {
2347 if ($properties[
'section'] === self::PART_HEADER) {
2355 if ($this->moveJsFromHeaderToFooter) {
2371 if (!empty($this->jsFiles)) {
2372 foreach ($this->jsFiles as $file => $properties) {
2375 $async = ($properties[
'async']) ?
' async="async"' :
'';
2376 $integrity = ($properties[
'integrity']) ?
' integrity="' . htmlspecialchars($properties[
'integrity']) .
'"' :
'';
2377 $tag =
'<script src="' . htmlspecialchars($file) .
'" type="' . htmlspecialchars($properties[
'type']) .
'"' . $async . $integrity .
'></script>';
2378 if ($properties[
'allWrap']) {
2379 $wrapArr = explode($properties[
'splitChar'] ?:
'|', $properties[
'allWrap'], 2);
2380 $tag = $wrapArr[0] . $tag . $wrapArr[1];
2383 if ($properties[
'forceOnTop']) {
2384 if ($properties[
'section'] === self::PART_HEADER) {
2390 if ($properties[
'section'] === self::PART_HEADER) {
2398 if ($this->moveJsFromHeaderToFooter) {
2414 if (!empty($this->jsInline)) {
2415 foreach ($this->jsInline as $name => $properties) {
2416 $jsCode =
'/*' . htmlspecialchars($name) .
'*/' . LF . $properties[
'code'] . LF;
2417 if ($properties[
'forceOnTop']) {
2418 if ($properties[
'section'] === self::PART_HEADER) {
2424 if ($properties[
'section'] === self::PART_HEADER) {
2433 $jsInline = $this->inlineJavascriptWrap[0] .
$jsInline . $this->inlineJavascriptWrap[1];
2438 if ($this->moveJsFromHeaderToFooter) {
2457 if (!isset($this->lang) || !isset($this->charSet)) {
2458 throw new \RuntimeException(
'Language and character encoding are not set.', 1284906026);
2460 $labelsFromFile = array();
2461 $allLabels = $this->readLLfile($fileRef, $errorMode);
2462 if ($allLabels !==
false) {
2464 if ($this->lang !==
'default' && isset($allLabels[$this->lang])) {
2465 $labels = array_merge($allLabels[
'default'], $allLabels[$this->lang]);
2467 $labels = $allLabels[
'default'];
2470 foreach ($labels as $label => $value) {
2472 if ($selectionPrefix ===
'' || strpos($label, $selectionPrefix) === 0) {
2474 $label = str_replace($stripFromSelectionName,
'', $label);
2475 $labelsFromFile[$label] = $value;
2478 $this->inlineLanguageLabels = array_merge($this->inlineLanguageLabels, $labelsFromFile);
2489 protected function readLLfile($fileRef, $errorMode = 0)
2494 if ($this->lang !==
'default') {
2495 $languages = array_reverse($this->languageDependencies);
2497 if (empty($languages)) {
2498 $languages[] =
'default';
2501 $languages = array(
'default');
2504 $localLanguage = array();
2505 foreach ($languages as $language) {
2506 $tempLL = $languageFactory->getParsedData($fileRef, $language, $this->charSet, $errorMode);
2508 $localLanguage[
'default'] = $tempLL[
'default'];
2509 if (!isset($localLanguage[$this->lang])) {
2510 $localLanguage[
$this->lang] = $localLanguage[
'default'];
2512 if ($this->lang !==
'default' && isset($tempLL[$language])) {
2515 \TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($localLanguage[$this->lang], $tempLL[$language],
true,
false);
2519 return $localLanguage;
2547 if ($this->concatenateFiles || $this->concatenateJavascript) {
2548 if (!empty(
$GLOBALS[
'TYPO3_CONF_VARS'][TYPO3_MODE][
'jsConcatenateHandler'])) {
2551 'jsLibs' => &$this->jsLibs,
2552 'jsFiles' => &$this->jsFiles,
2553 'jsFooterFiles' => &$this->jsFooterFiles,
2554 'headerData' => &$this->headerData,
2555 'footerData' => &$this->footerData
2559 $this->jsLibs = $this->
getCompressor()->concatenateJsFiles($this->jsLibs);
2560 $this->jsFiles = $this->
getCompressor()->concatenateJsFiles($this->jsFiles);
2561 $this->jsFooterFiles = $this->
getCompressor()->concatenateJsFiles($this->jsFooterFiles);
2573 if ($this->concatenateFiles || $this->concatenateCss) {
2574 if (!empty(
$GLOBALS[
'TYPO3_CONF_VARS'][TYPO3_MODE][
'cssConcatenateHandler'])) {
2577 'cssFiles' => &$this->cssFiles,
2578 'cssLibs' => &$this->cssLibs,
2579 'headerData' => &$this->headerData,
2580 'footerData' => &$this->footerData
2584 $cssOptions = array();
2585 if (TYPO3_MODE ===
'BE') {
2586 $cssOptions = array(
'baseDirectories' =>
$GLOBALS[
'TBE_TEMPLATE']->getSkinStylesheetDirectories());
2588 $this->cssLibs = $this->
getCompressor()->concatenateCssFiles($this->cssLibs, $cssOptions);
2589 $this->cssFiles = $this->
getCompressor()->concatenateCssFiles($this->cssFiles, $cssOptions);
2612 if ($this->compressCss) {
2613 if (!empty(
$GLOBALS[
'TYPO3_CONF_VARS'][TYPO3_MODE][
'cssCompressHandler'])) {
2616 'cssInline' => &$this->cssInline,
2617 'cssFiles' => &$this->cssFiles,
2618 'cssLibs' => &$this->cssLibs,
2619 'headerData' => &$this->headerData,
2620 'footerData' => &$this->footerData
2624 $this->cssLibs = $this->
getCompressor()->compressCssFiles($this->cssLibs);
2625 $this->cssFiles = $this->
getCompressor()->compressCssFiles($this->cssFiles);
2637 if ($this->compressJavascript) {
2638 if (!empty(
$GLOBALS[
'TYPO3_CONF_VARS'][TYPO3_MODE][
'jsCompressHandler'])) {
2641 'jsInline' => &$this->jsInline,
2642 'jsFooterInline' => &$this->jsFooterInline,
2643 'jsLibs' => &$this->jsLibs,
2644 'jsFiles' => &$this->jsFiles,
2645 'jsFooterFiles' => &$this->jsFooterFiles,
2646 'headerData' => &$this->headerData,
2647 'footerData' => &$this->footerData
2652 if (!empty($this->jsInline)) {
2653 foreach ($this->jsInline as $name => $properties) {
2654 if ($properties[
'compress']) {
2658 $this->compressError .=
'Error with minify JS Inline Block "' . $name .
'": ' . $error . LF;
2663 $this->jsLibs = $this->
getCompressor()->compressJsFiles($this->jsLibs);
2664 $this->jsFiles = $this->
getCompressor()->compressJsFiles($this->jsFiles);
2665 $this->jsFooterFiles = $this->
getCompressor()->compressJsFiles($this->jsFooterFiles);
2677 if ($this->compressor === null) {
2693 switch (TYPO3_MODE) {
2695 if ($this->compressJavascript) {
2702 if ($this->compressJavascript) {
2742 if (is_array(
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
't3lib/class.t3lib_pagerenderer.php'][
'render-preProcess'])) {
2744 'jsLibs' => &$this->jsLibs,
2745 'jsFooterLibs' => &$this->jsFooterLibs,
2746 'jsFiles' => &$this->jsFiles,
2747 'jsFooterFiles' => &$this->jsFooterFiles,
2748 'cssFiles' => &$this->cssFiles,
2749 'headerData' => &$this->headerData,
2750 'footerData' => &$this->footerData,
2751 'jsInline' => &$this->jsInline,
2752 'jsFooterInline' => &$this->jsFooterInline,
2753 'cssInline' => &$this->cssInline
2755 foreach (
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
't3lib/class.t3lib_pagerenderer.php'][
'render-preProcess'] as $hook) {
2768 if (is_array(
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
't3lib/class.t3lib_pagerenderer.php'][
'render-postTransform'])) {
2770 'jsLibs' => &$this->jsLibs,
2771 'jsFooterLibs' => &$this->jsFooterLibs,
2772 'jsFiles' => &$this->jsFiles,
2773 'jsFooterFiles' => &$this->jsFooterFiles,
2774 'cssFiles' => &$this->cssFiles,
2775 'headerData' => &$this->headerData,
2776 'footerData' => &$this->footerData,
2777 'jsInline' => &$this->jsInline,
2778 'jsFooterInline' => &$this->jsFooterInline,
2779 'cssInline' => &$this->cssInline
2781 foreach (
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
't3lib/class.t3lib_pagerenderer.php'][
'render-postTransform'] as $hook) {
2803 if (is_array(
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
't3lib/class.t3lib_pagerenderer.php'][
'render-postProcess'])) {
2810 'headerData' => &$this->headerData,
2811 'footerData' => &$this->footerData,
2814 'xmlPrologAndDocType' => &$this->xmlPrologAndDocType,
2815 'htmlTag' => &$this->htmlTag,
2816 'headTag' => &$this->headTag,
2817 'charSet' => &$this->charSet,
2818 'metaCharsetTag' => &$this->metaCharsetTag,
2819 'shortcutTag' => &$this->shortcutTag,
2820 'inlineComments' => &$this->inlineComments,
2821 'baseUrl' => &$this->baseUrl,
2822 'baseUrlTag' => &$this->baseUrlTag,
2823 'favIcon' => &$this->favIcon,
2824 'iconMimeType' => &$this->iconMimeType,
2825 'titleTag' => &$this->titleTag,
2826 'title' => &$this->title,
2827 'metaTags' => &$this->metaTags,
2830 'bodyContent' => &$this->bodyContent
2832 foreach (
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
't3lib/class.t3lib_pagerenderer.php'][
'render-postProcess'] as $hook) {