diff options
Diffstat (limited to 'core/templates/layout.user.php')
-rw-r--r-- | core/templates/layout.user.php | 195 |
1 files changed, 43 insertions, 152 deletions
diff --git a/core/templates/layout.user.php b/core/templates/layout.user.php index 4efe072a5bb..47cced308bc 100644 --- a/core/templates/layout.user.php +++ b/core/templates/layout.user.php @@ -1,11 +1,17 @@ <?php /** + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2011-2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only + */ + +/** * @var \OC_Defaults $theme * @var array $_ */ $getUserAvatar = static function (int $size) use ($_): string { - return \OC::$server->getURLGenerator()->linkToRoute('core.avatar.getAvatar', [ + return \OCP\Server::get(\OCP\IURLGenerator::class)->linkToRoute('core.avatar.getAvatar', [ 'userId' => $_['user_uid'], 'size' => $size, 'v' => $_['userAvatarVersion'] @@ -13,16 +19,21 @@ $getUserAvatar = static function (int $size) use ($_): string { } ?><!DOCTYPE html> -<html class="ng-csp" data-placeholder-focus="false" lang="<?php p($_['language']); ?>" data-locale="<?php p($_['locale']); ?>" > +<html class="ng-csp" data-placeholder-focus="false" lang="<?php p($_['language']); ?>" data-locale="<?php p($_['locale']); ?>" translate="no" > <head data-user="<?php p($_['user_uid']); ?>" data-user-displayname="<?php p($_['user_displayname']); ?>" data-requesttoken="<?php p($_['requesttoken']); ?>"> <meta charset="utf-8"> <title> <?php - p(!empty($_['application'])?$_['application'].' - ':''); - p($theme->getTitle()); - ?> + p(!empty($_['pageTitle']) && (empty($_['application']) || $_['pageTitle'] !== $_['application']) ? $_['pageTitle'] . ' - ' : ''); +p(!empty($_['application']) ? $_['application'] . ' - ' : ''); +p($theme->getTitle()); +?> </title> - <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0"> + <meta name="csp-nonce" nonce="<?php p($_['cspNonce']); /* Do not pass into "content" to prevent exfiltration */ ?>"> + <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0<?php if (isset($_['viewport_maximum_scale'])) { + p(', maximum-scale=' . $_['viewport_maximum_scale']); + } ?>"> + <?php if ($theme->getiTunesAppId() !== '') { ?> <meta name="apple-itunes-app" content="app-id=<?php p($theme->getiTunesAppId()); ?>"> <?php } ?> @@ -35,168 +46,48 @@ $getUserAvatar = static function (int $size) use ($_): string { <link rel="apple-touch-icon" href="<?php print_unescaped(image_path($_['appid'], 'favicon-touch.png')); ?>"> <link rel="apple-touch-icon-precomposed" href="<?php print_unescaped(image_path($_['appid'], 'favicon-touch.png')); ?>"> <link rel="mask-icon" sizes="any" href="<?php print_unescaped(image_path($_['appid'], 'favicon-mask.svg')); ?>" color="<?php p($theme->getColorPrimary()); ?>"> - <link rel="manifest" href="<?php print_unescaped(image_path($_['appid'], 'manifest.json')); ?>"> + <link rel="manifest" href="<?php print_unescaped(image_path($_['appid'], 'manifest.json')); ?>" crossorigin="use-credentials"> <?php emit_css_loading_tags($_); ?> <?php emit_script_loading_tags($_); ?> <?php print_unescaped($_['headers']); ?> </head> - <body id="<?php p($_['bodyid']);?>" <?php foreach ($_['enabledThemes'] as $themeId) { - p("data-theme-$themeId "); - }?>> - <?php include 'layout.noscript.warning.php'; ?> + <body dir="<?php p($_['direction']); ?>" id="<?php p($_['bodyid']);?>" <?php foreach ($_['enabledThemes'] as $themeId) { + p("data-theme-$themeId "); + }?> data-themes=<?php p(join(',', $_['enabledThemes'])) ?>> + <?php include 'layout.noscript.warning.php'; ?> + <?php include 'layout.initial-state.php'; ?> - <?php foreach ($_['initialStates'] as $app => $initialState) { ?> - <input type="hidden" id="initial-state-<?php p($app); ?>" value="<?php p(base64_encode($initialState)); ?>"> - <?php }?> - - <a href="#app-content" class="button primary skip-navigation skip-content"><?php p($l->t('Skip to main content')); ?></a> - <a href="#app-navigation" class="button primary skip-navigation"><?php p($l->t('Skip to navigation of app')); ?></a> - - <div id="notification-container"> - <div id="notification"></div> + <div id="skip-actions"> + <?php if ($_['id-app-content'] !== null) { ?><a href="<?php p($_['id-app-content']); ?>" class="button primary skip-navigation skip-content"><?php p($l->t('Skip to main content')); ?></a><?php } ?> + <?php if ($_['id-app-navigation'] !== null) { ?><a href="<?php p($_['id-app-navigation']); ?>" class="button primary skip-navigation"><?php p($l->t('Skip to navigation of app')); ?></a><?php } ?> </div> - <header role="banner" id="header"> - <div class="header-left"> + + <header id="header"> + <div class="header-start"> <a href="<?php print_unescaped($_['logoUrl'] ?: link_to('', 'index.php')); ?>" + aria-label="<?php p($l->t('Go to %s', [$_['logoUrl'] ?: $_['defaultAppName']])); ?>" id="nextcloud"> - <div class="logo logo-icon"> - <h1 class="hidden-visually"> - <?php p($theme->getName()); ?> <?php p(!empty($_['application'])?$_['application']: $l->t('Apps')); ?> - </h1> - </div> + <div class="logo logo-icon"></div> </a> - <ul id="appmenu"> - <?php foreach ($_['navigation'] as $entry): ?> - <li data-id="<?php p($entry['id']); ?>" class="hidden" tabindex="-1"> - <a href="<?php print_unescaped($entry['href']); ?>" - <?php if (isset($entry['target']) && $entry['target']): ?> target="_blank" rel="noreferrer noopener"<?php endif; ?> - <?php if ($entry['active']): ?> class="active"<?php endif; ?> - aria-label="<?php p($entry['name']); ?>"> - <svg width="24" height="20" viewBox="0 0 24 20" alt=""<?php if ($entry['unread'] !== 0) { ?> class="has-unread"<?php } ?>> - <defs> - <mask id="hole"> - <rect width="100%" height="100%" fill="white"/> - <circle r="4.5" cx="21" cy="3" fill="black"/> - </mask> - </defs> - <image x="2" y="0" width="20" height="20" preserveAspectRatio="xMinYMin meet" xlink:href="<?php print_unescaped($entry['icon'] . '?v=' . $_['versionHash']); ?>" style="<?php if ($entry['unread'] !== 0) { ?>mask: url("#hole");<?php } ?>" class="app-icon"></image> - <circle class="app-icon-notification" r="3" cx="21" cy="3" fill="red"/> - </svg> - <div class="unread-counter" aria-hidden="true"><?php p($entry['unread']); ?></div> - <span> - <?php p($entry['name']); ?> - </span> - </a> - </li> - <?php endforeach; ?> - <li id="more-apps" class="menutoggle" - aria-haspopup="true" aria-controls="navigation" aria-expanded="false"> - <a href="#" aria-label="<?php p($l->t('More apps')); ?>"> - <div class="icon-more-white"></div> - <span><?php p($l->t('More')); ?></span> - </a> - </li> - </ul> - - <nav role="navigation"> - <div id="navigation" style="display: none;" aria-label="<?php p($l->t('More apps menu')); ?>"> - <div id="apps"> - <ul> - <?php foreach ($_['navigation'] as $entry): ?> - <li data-id="<?php p($entry['id']); ?>"> - <a href="<?php print_unescaped($entry['href']); ?>" - <?php if (isset($entry['target']) && $entry['target']): ?> target="_blank" rel="noreferrer noopener"<?php endif; ?> - <?php if ($entry['active']): ?> class="active"<?php endif; ?> - aria-label="<?php p($entry['name']); ?>"> - <svg width="20" height="20" viewBox="0 0 20 20" alt=""<?php if ($entry['unread'] !== 0) { ?> class="has-unread"<?php } ?>> - <defs> - <filter id="invertMenuMore-<?php p($entry['id']); ?>"><feColorMatrix in="SourceGraphic" type="matrix" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"></feColorMatrix></filter> - <mask id="hole"> - <rect width="100%" height="100%" fill="white"/> - <circle r="4.5" cx="17" cy="3" fill="black"/> - </mask> - </defs> - <image x="0" y="0" width="16" height="16" preserveAspectRatio="xMinYMin meet" filter="url(#invertMenuMore-<?php p($entry['id']); ?>)" xlink:href="<?php print_unescaped($entry['icon'] . '?v=' . $_['versionHash']); ?>" style="<?php if ($entry['unread'] !== 0) { ?>mask: url("#hole");<?php } ?>" class="app-icon"></image> - <circle class="app-icon-notification" r="3" cx="17" cy="3" fill="red"/> - </svg> - <div class="unread-counter" aria-hidden="true"><?php p($entry['unread']); ?></div> - <span class="app-title"><?php p($entry['name']); ?></span> - </a> - </li> - <?php endforeach; ?> - </ul> - </div> - </div> - </nav> - + <nav id="header-start__appmenu"></nav> </div> - <div class="header-right"> - <div id="notifications"></div> + <div class="header-end"> <div id="unified-search"></div> - <div id="contactsmenu"> - <div class="icon-contacts menutoggle" tabindex="0" role="button" - aria-haspopup="true" aria-controls="contactsmenu-menu" aria-expanded="false"> - <span class="hidden-visually"><?php p($l->t('Contacts'));?></span> - </div> - <div id="contactsmenu-menu" class="menu" - aria-label="<?php p($l->t('Contacts menu'));?>"></div> - </div> - <div id="settings"> - <div id="expand" tabindex="0" role="button" class="menutoggle" - aria-label="<?php p($l->t('Settings'));?>" - aria-haspopup="true" aria-controls="expanddiv" aria-expanded="false"> - <div id="avatardiv-menu" class="avatardiv<?php if ($_['userAvatarSet']) { - print_unescaped(' avatardiv-shown'); - } else { - print_unescaped('" style="display: none'); - } ?>" - data-user="<?php p($_['user_uid']); ?>" - data-displayname="<?php p($_['user_displayname']); ?>" - <?php - if ($_['userAvatarSet']) { - $avatar32 = $getUserAvatar(32); ?> data-avatar="<?php p($avatar32); ?>" - <?php - } ?>> - <?php - if ($_['userAvatarSet']) {?> - <img alt="" width="32" height="32" - src="<?php p($avatar32);?>" - srcset="<?php p($getUserAvatar(64));?> 2x, <?php p($getUserAvatar(128));?> 4x" - > - <?php } ?> - </div> - </div> - <nav class="settings-menu" id="expanddiv" style="display:none;" - aria-label="<?php p($l->t('Settings menu'));?>"> - <ul> - <?php foreach ($_['settingsnavigation'] as $entry):?> - <li data-id="<?php p($entry['id']); ?>"> - <a href="<?php print_unescaped($entry['href']); ?>" - <?php if ($entry["active"]): ?> class="active"<?php endif; ?>> - <img alt="" src="<?php print_unescaped($entry['icon'] . '?v=' . $_['versionHash']); ?>"> - <?php p($entry['name']) ?> - </a> - </li> - <?php endforeach; ?> - </ul> - </nav> - </div> + <div id="notifications"></div> + <div id="contactsmenu"></div> + <div id="user-menu"></div> </div> </header> - <div id="sudo-login-background" class="hidden"></div> - <form id="sudo-login-form" class="hidden" method="POST"> - <label> - <?php p($l->t('This action requires you to confirm your password')); ?><br/> - <input type="password" class="question" autocomplete="new-password" name="question" value=" <?php /* Hack against browsers ignoring autocomplete="off" */ ?>" - placeholder="<?php p($l->t('Confirm your password')); ?>" /> - </label> - <input class="confirm" value="<?php p($l->t('Confirm')); ?>" type="submit"> - </form> - - <div id="content" class="app-<?php p($_['appid']) ?>" role="main"> + <div id="content" class="app-<?php p($_['appid']) ?>"> + <h1 class="hidden-visually" id="page-heading-level-1"> + <?php p((!empty($_['application']) && !empty($_['pageTitle']) && $_['application'] != $_['pageTitle']) + ? $_['application'] . ': ' . $_['pageTitle'] + : (!empty($_['pageTitle']) ? $_['pageTitle'] : $theme->getName()) + ); ?> + </h1> <?php print_unescaped($_['content']); ?> </div> <div id="profiler-toolbar"></div> |