diff --git a/libraries/joomla/document/renderer/html/head.php b/libraries/joomla/document/renderer/html/head.php
index 3d6f747b0192a..9409d41cf4317 100644
--- a/libraries/joomla/document/renderer/html/head.php
+++ b/libraries/joomla/document/renderer/html/head.php
@@ -63,16 +63,78 @@ public function fetchHead($document)
$app->triggerEvent('onBeforeCompileHead');
// Get line endings
- $lnEnd = $document->_getLineEnd();
- $tab = $document->_getTab();
- $tagEnd = ' />';
- $buffer = '';
- $mediaVersion = $document->getMediaVersion();
+ $lnEnd = $document->_getLineEnd();
+
+ // Get the meta tags (also base, title, etc.)
+ $buffer = $this->fetchMetaTags($document);
+
+ // Get (non-stylesheet) link tags if any
+ if (!empty($document->_links))
+ {
+ $buffer = array_merge($buffer, $this->fetchLinkTags($document));
+ }
+
+ // Get the stylesheets
+ if (!empty($document->_styleSheets))
+ {
+ $buffer = array_merge($buffer, $this->fetchStyleSheets($document));
+ }
+
+ // Get the style declarations
+ if (!empty($document->_style))
+ {
+ $buffer = array_merge($buffer, $this->fetchStyleDeclarations($document));
+ }
+
+ // Get script options
+ $scriptOptions = $document->getScriptOptions();
+
+ if (!empty($scriptOptions))
+ {
+ $buffer = array_merge($buffer, $this->fetchScriptOptions($document));
+ }
+
+ // Get scripts (loaded as external files)
+ if (!empty($document->_scripts))
+ {
+ $buffer = array_merge($buffer, $this->fetchScripts($document));
+ }
+
+ // Get script declarations
+ if (!empty($document->_script))
+ {
+ $buffer = array_merge($buffer, $this->fetchScriptDeclarations($document));
+ }
+
+ // Get custom tags
+ if (!empty($document->_custom))
+ {
+ $buffer = array_merge($buffer, $this->fetchCustomTags($document));
+ }
+
+ return implode($lnEnd, $buffer);
+ }
+
+ /**
+ * Gets the meta, title, and base tags as an array.
+ *
+ * @param JDocumentHtml $document The document for which the head will be created
+ *
+ * @return array The tags
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ protected function fetchMetaTags($document)
+ {
+ $tab = $document->_getTab();
+ $isHtml5 = $document->isHtml5();
+ $tagEnd = $isHtml5 ? '>' : '/>';
+ $buffer = array();
// Generate charset when using HTML5 (should happen first)
- if ($document->isHtml5())
+ if ($isHtml5)
{
- $buffer .= $tab . '' . $lnEnd;
+ $buffer[] = $tab . '' . $lnEnd;
+ $buffer[] = $tab . ' $content)
{
- if ($type == 'http-equiv' && !($document->isHtml5() && $name == 'content-type'))
- {
- $buffer .= $tab . '' . $lnEnd;
- }
- elseif ($type != 'http-equiv' && !empty($content))
+ // Html5 doesn't need content-type and we don't need empty meta tags
+ if (($isHtml5 && $type == 'http-equiv' && $name == 'content-type') || empty($content))
{
- $buffer .= $tab . '' . $lnEnd;
+ continue;
}
+
+ $buffer[] = $tab . '' . $lnEnd;
+ $buffer[] = $tab . '' . $lnEnd;
+ $buffer[] = $tab . '' . htmlspecialchars($document->getTitle(), ENT_COMPAT, 'UTF-8') . '' . $lnEnd;
+ $buffer[] = $tab . '
' . htmlspecialchars($document->getTitle(), ENT_COMPAT, 'UTF-8') . '';
+
+ return $buffer;
+ }
+
+ /**
+ * Gets the (non-stylesheet) link tags as an array.
+ *
+ * @param JDocumentHtml $document The document for which the head will be created
+ *
+ * @return array The tags
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ protected function fetchLinkTags($document)
+ {
+ $tab = $document->_getTab();
+ $isHtml5 = $document->isHtml5();
+ $tagEnd = $isHtml5 ? '>' : '/>';
+ $buffer = array();
// Generate link declarations
foreach ($document->_links as $link => $linkAtrr)
{
- $buffer .= $tab . '_getTab();
+ $isHtml5 = $document->isHtml5();
+ $mediaVersion = $document->getMediaVersion();
+ $tagEnd = $isHtml5 ? ' >' : ' />';
+ $buffer = array();
+
$defaultCssMimes = array('text/css');
// Generate stylesheet links
foreach ($document->_styleSheets as $src => $attribs)
{
- // Check if stylesheet uses IE conditional statements.
- $conditional = isset($attribs['options']) && isset($attribs['options']['conditional']) ? $attribs['options']['conditional'] : null;
+ $conditional = null;
+ $attr = array('rel="stylesheet"');
- // Check if script uses media version.
- if (isset($attribs['options']['version']) && $attribs['options']['version'] && strpos($src, '?') === false
- && ($mediaVersion || $attribs['options']['version'] !== 'auto'))
+ if (isset($attribs['mime']) && (!$isHtml5 || !in_array($attribs['mime'], $defaultCssMimes)))
{
- $src .= '?' . ($attribs['options']['version'] === 'auto' ? $mediaVersion : $attribs['options']['version']);
+ $attr[] = 'type="' . $attribs['mime'] . '"';
}
- $buffer .= $tab;
-
- // This is for IE conditional statements support.
- if (!is_null($conditional))
+ if (isset($attribs['options']) && is_array($attribs['options']))
{
- $buffer .= '';
+ $attr[] = 'media="' . $attribs['media'] . '"';
+ }
+
+ if (isset($attribs['attribs']) && is_array($attribs['attribs']) && !empty($attribs['attribs']))
+ {
+ $attr[] = ArrayHelper::toString($attribs['attribs']);
}
- $buffer .= $lnEnd;
+ $buffer[] = $tab . '_getTab();
+ $buffer = array();
+
+ $defaultCssMimes = array('text/css');
+
// Generate stylesheet declarations
foreach ($document->_style as $type => $content)
{
- $buffer .= $tab . '' . $lnEnd;
+ $buffer[] = $tab . '';
}
- // Generate scripts options
- $scriptOptions = $document->getScriptOptions();
-
- if (!empty($scriptOptions))
- {
- $buffer .= $tab . '' . $lnEnd;
- }
+ /**
+ * Gets the external file loading script tags as an array.
+ *
+ * @param JDocumentHtml $document The document for which the head will be created
+ *
+ * @return array The tags
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ protected function fetchScripts($document)
+ {
+ $tab = $document->_getTab();
+ $isHtml5 = $document->isHtml5();
+ $buffer = array();
$defaultJsMimes = array('text/javascript', 'application/javascript', 'text/x-javascript', 'application/x-javascript');
$html5NoValueAttributes = array('defer', 'async');
+ $mediaVersion = $document->getMediaVersion();
// Generate script file links
foreach ($document->_scripts as $src => $attribs)
{
- // Check if script uses IE conditional statements.
- $conditional = isset($attribs['options']) && isset($attribs['options']['conditional']) ? $attribs['options']['conditional'] : null;
-
// Check if script uses media version.
if (isset($attribs['options']['version']) && $attribs['options']['version'] && strpos($src, '?') === false
&& ($mediaVersion || $attribs['options']['version'] !== 'auto'))
@@ -259,15 +359,7 @@ public function fetchHead($document)
$src .= '?' . ($attribs['options']['version'] === 'auto' ? $mediaVersion : $attribs['options']['version']);
}
- $buffer .= $tab;
-
- // This is for IE conditional statements support.
- if (!is_null($conditional))
- {
- $buffer .= '';
- }
+ $buffer[] = $tab .
+ (is_null($conditional) ? '' : '');
+ }
+
+ return $buffer;
+ }
- $buffer .= $lnEnd;
+ /**
+ * Gets a script tag containing the Joomla options storage.
+ *
+ * @param JDocumentHtml $document The document for which the head will be created
+ *
+ * @return array The tags
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ protected function fetchScriptOptions($document)
+ {
+ // Generate scripts options
+ $scriptOptions = $document->getScriptOptions();
+
+ if (empty($scriptOptions))
+ {
+ return array();
}
+ $tab = $document->_getTab();
+
+ $prettyPrint = (JDEBUG && defined('JSON_PRETTY_PRINT') ? JSON_PRETTY_PRINT : false);
+ $jsonOptions = json_encode($scriptOptions, $prettyPrint);
+ $jsonOptions = $jsonOptions ? $jsonOptions : '{}';
+
+ $buffer = $tab .
+ '';
+
+ return array($buffer);
+ }
+
+ /**
+ * Gets a script tag containing javascript declarations as an array.
+ *
+ * @param JDocumentHtml $document The document for which the head will be created
+ *
+ * @return array The tags
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ protected function fetchScriptDeclarations($document)
+ {
+ $tab = $document->_getTab();
+ $isHtml5 = $document->isHtml5();
+ $buffer = array();
+
+ $defaultJsMimes = array('text/javascript', 'application/javascript', 'text/x-javascript', 'application/x-javascript');
+
// Generate script declarations
foreach ($document->_script as $type => $content)
{
- $buffer .= $tab . '' . $lnEnd;
+ $buffer[] = $tab . '';
}
+ return $buffer;
+ }
+
+ /**
+ * Gets the custom tags as an array.
+ *
+ * @param JDocumentHtml $document The document for which the head will be created
+ *
+ * @return array The tags
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ protected function fetchCustomTags($document)
+ {
+ $tab = $document->_getTab();
+ $buffer = array();
+
// Output the custom tags - array_unique makes sure that we don't output the same tags twice
foreach (array_unique($document->_custom) as $custom)
{
- $buffer .= $tab . $custom . $lnEnd;
+ $buffer[] = $tab . $custom;
}
return ltrim($buffer, $tab);