diff --git a/program/include/rcmail_output_html.php b/program/include/rcmail_output_html.php index 669812ae8..62042806f 100644 --- a/program/include/rcmail_output_html.php +++ b/program/include/rcmail_output_html.php @@ -41,6 +41,8 @@ class rcmail_output_html extends rcmail_output protected $script_files = array(); protected $css_files = array(); protected $scripts = array(); + protected $meta_tags = array(); + protected $link_tags = array('shortcut icon' => ''); protected $header = ''; protected $footer = ''; protected $body = ''; @@ -348,6 +350,10 @@ EOF; $this->app->load_language($_SESSION['language'], $texts); } } + + // Use array_merge() here to allow for global default and extended skins + $this->meta_tags = array_merge($this->meta_tags, (array) $meta['meta']); + $this->link_tags = array_merge($this->link_tags, (array) $meta['links']); } /** @@ -1371,12 +1377,52 @@ EOF; $content = $this->frame($attrib, true); } - else if ($object == 'favicon') { - if ($template_logo = $this->get_template_logo(':favicon', true)) { - $content = html::tag('link', array('rel' => 'shortcut icon', 'href' => $template_logo)); + else if (in_array($object, array('meta', 'links'))) { + if ($object == 'meta') { + $source = 'meta_tags'; + $tag = 'meta'; + $key = 'name'; + $param = 'content'; + } + elseif ($object == 'links') { + $source = 'link_tags'; + $tag = 'link'; + $key = 'rel'; + $param = 'href'; } - else if ($file = $this->config->get('favicon', '/images/favicon.ico')) { - $content = html::tag('link', array('rel' => 'shortcut icon', 'href' => $file)); + + foreach ($this->$source as $name => $vars) { + /* + $vars can be in many forms: + *) string + *) array('key' => 'val') + *) array(string, string) + *) array(array(), string) + *) array(array('key' => 'val'), array('key' => 'val')) + normalise this for processing by checking for string array keys + */ + $vars = is_array($vars) ? (count(array_filter(array_keys($vars), 'is_string')) > 0 ? array($vars) : $vars) : array($vars); + + foreach ($vars as $args) { + // skip unset headers e.g. when extending a skin and removing a header defined in the parent + if ($args === false) { + continue; + } + + $args = is_array($args) ? $args : array($param => $args); + + // special handling for favicon + if ($object == 'links' && $name == 'shortcut icon' && empty($args[$param])) { + if ($href = $this->get_template_logo(':favicon', true)) { + $args[$param] = $href; + } + else if ($href = $this->config->get('favicon', '/images/favicon.ico')) { + $args[$param] = $href; + } + } + + $content .= html::tag($tag, array($key => $name, 'nl' => true) + $args); + } } } diff --git a/skins/classic/includes/links.html b/skins/classic/includes/links.html index 16efb5653..d1de13514 100644 --- a/skins/classic/includes/links.html +++ b/skins/classic/includes/links.html @@ -1,9 +1,10 @@ - + .css" /> - \ No newline at end of file + + \ No newline at end of file diff --git a/skins/elastic/meta.json b/skins/elastic/meta.json index c35c85f8b..249e22661 100644 --- a/skins/elastic/meta.json +++ b/skins/elastic/meta.json @@ -9,5 +9,10 @@ "embed_css_location": "/styles/embed.css", "editor_css_location": "/styles/embed.css", "media_browser_css_location": "none" + }, + "meta": { + "viewport": "width=device-width, initial-scale=1.0, shrink-to-fit=no, maximum-scale=1.0", + "theme-color": "#f4f4f4", + "msapplication-navbutton-color": "#f4f4f4" } } diff --git a/skins/elastic/templates/includes/layout.html b/skins/elastic/templates/includes/layout.html index 63bcb9ab1..e71b691b3 100644 --- a/skins/elastic/templates/includes/layout.html +++ b/skins/elastic/templates/includes/layout.html @@ -15,8 +15,7 @@ <roundcube:object name="pagetitle" /> - - + @@ -26,6 +25,7 @@ + "> diff --git a/skins/larry/includes/links.html b/skins/larry/includes/links.html index 845dfa2c2..a28e89b3c 100644 --- a/skins/larry/includes/links.html +++ b/skins/larry/includes/links.html @@ -1,9 +1,10 @@ - + .css" /> +