From 9829478d1a2e2427e36a40907d4ef144e6db3110 Mon Sep 17 00:00:00 2001 From: WouterRademaker Date: Mon, 5 Aug 2024 13:37:33 +0200 Subject: [PATCH 1/3] Pageform_441 --- resources/styles/_extensionfixes.scss | 6 + src/ChameleonTemplate.php | 2 +- src/Components/CategoryLinks.php | 6 +- src/Components/Component.php | 11 +- src/Components/Container.php | 8 +- src/Components/ContentBody.php | 6 +- src/Components/ContentHeader.php | 6 +- src/Components/FooterIcons.php | 6 +- src/Components/FooterInfo.php | 6 +- src/Components/FooterPlaces.php | 6 +- src/Components/Html.php | 6 +- src/Components/Indicators.php | 6 +- src/Components/Logo.php | 6 +- src/Components/MainContent.php | 6 +- src/Components/Menu.php | 6 +- src/Components/Message.php | 6 +- src/Components/Modifications/Modification.php | 6 +- src/Components/NavMenu.php | 6 +- src/Components/NavbarHorizontal.php | 6 +- src/Components/NavbarHorizontal/LangLinks.php | 6 +- src/Components/NavbarHorizontal/Logo.php | 6 +- src/Components/NavbarHorizontal/Menu.php | 6 +- src/Components/NavbarHorizontal/NavMenu.php | 6 +- src/Components/NavbarHorizontal/PageTools.php | 6 +- .../NavbarHorizontal/PersonalTools.php | 6 +- .../NavbarHorizontal/PersonalTools.php.orig | 324 ++++++++++++++++++ src/Components/NavbarHorizontal/SearchBar.php | 6 +- src/Components/NavbarHorizontal/Toolbox.php | 6 +- src/Components/NewtalkNotifier.php | 6 +- src/Components/PageTools.php | 6 +- src/Components/PersonalTools.php | 6 +- src/Components/SearchBar.php | 6 +- src/Components/Silent.php | 6 +- src/Components/SiteNotice.php | 6 +- src/Components/Structure.php | 5 +- src/Components/Toc.php | 6 +- 36 files changed, 500 insertions(+), 36 deletions(-) create mode 100644 src/Components/NavbarHorizontal/PersonalTools.php.orig diff --git a/resources/styles/_extensionfixes.scss b/resources/styles/_extensionfixes.scss index a64d2e68..a1b5a5b5 100644 --- a/resources/styles/_extensionfixes.scss +++ b/resources/styles/_extensionfixes.scss @@ -111,3 +111,9 @@ .wikiEditor-ui * { box-sizing: content-box; } + +/* Extension PageForm */ +form#pfForm { + clear: both; + border-top: $hr-border-width solid $hr-border-color; +} diff --git a/src/ChameleonTemplate.php b/src/ChameleonTemplate.php index 499a2e55..d5a29809 100644 --- a/src/ChameleonTemplate.php +++ b/src/ChameleonTemplate.php @@ -53,7 +53,7 @@ public function execute() { if ( !$bodyOnly ) { $this->html( 'headelement' ); } - echo $this->getSkin()->getComponentFactory()->getRootComponent()->getHtml(); + echo $this->getSkin()->getComponentFactory()->getRootComponent()->getHtml($this); if ( !$bodyOnly ) { $this->printTrail(); echo "\n"; diff --git a/src/Components/CategoryLinks.php b/src/Components/CategoryLinks.php index 0e39bf5f..68d2da18 100644 --- a/src/Components/CategoryLinks.php +++ b/src/Components/CategoryLinks.php @@ -40,9 +40,13 @@ class CategoryLinks extends Component { /** * Builds the HTML code for this component * + * @param ChameleonTemplate $tpl * @return String the HTML code */ - public function getHtml() { + public function getHtml($tpl = null) { + if ( !is_null( $tpl ) ) { + $this->setSkinTemplate( $tpl ); + } return $this->indent() . '' . $this->indent() . $this->getSkinTemplate()->get( 'catlinks' ); } diff --git a/src/Components/Component.php b/src/Components/Component.php index 6031f779..a7244aa8 100644 --- a/src/Components/Component.php +++ b/src/Components/Component.php @@ -120,6 +120,14 @@ public function getSkinTemplate() { return $this->mSkinTemplate; } + /** + * @param ChameleonTemplate $tpl + * @return void + */ + public function setSkinTemplate( $tpl ) { + $this->mSkinTemplate = $tpl; + } + /** * @since 1.1 * @return \Skins\Chameleon\Chameleon @@ -173,9 +181,10 @@ public function getDomElement() { /** * Builds the HTML code for this component * + * @param ChameleonTemplate $tpl * @return String the HTML code */ - abstract public function getHtml(); + abstract public function getHtml( $tpl ); /** * @return string[] the resource loader modules needed by this component diff --git a/src/Components/Container.php b/src/Components/Container.php index aa2c133d..340f0186 100644 --- a/src/Components/Container.php +++ b/src/Components/Container.php @@ -46,10 +46,14 @@ class Container extends Structure { /** * Builds the HTML code for the main container * + * @param ChameleonTemplate $tpl * @return String the HTML code * @throws \MWException */ - public function getHtml() { + public function getHtml($tpl = null) { + if ( !is_null( $tpl ) ) { + $this->setSkinTemplate( $tpl ); + } $attribs = [ 'class' => $this->getClassString() ]; $id = $this->getAttribute( 'id' ); @@ -60,7 +64,7 @@ public function getHtml() { $ret = $this->indent() . \Html::openElement( 'div', $attribs ); $this->indent( 1 ); - $ret .= parent::getHtml(); + $ret .= parent::getHtml( $tpl ); $ret .= $this->indent( -1 ) . ''; diff --git a/src/Components/ContentBody.php b/src/Components/ContentBody.php index e775bb69..1043767b 100644 --- a/src/Components/ContentBody.php +++ b/src/Components/ContentBody.php @@ -39,9 +39,13 @@ class ContentBody extends Component { /** * @inheritDoc + * @param ChameleonTemplate $tpl * @throws \MWException */ - public function getHtml(): string { +public function getHtml($tpl = null): string { + if ( !is_null( $tpl ) ) { + $this->setSkinTemplate( $tpl ); + } return $this->buildContentBody(); } diff --git a/src/Components/ContentHeader.php b/src/Components/ContentHeader.php index 4530122c..5d8b868c 100644 --- a/src/Components/ContentHeader.php +++ b/src/Components/ContentHeader.php @@ -39,9 +39,13 @@ class ContentHeader extends Component { /** * @inheritDoc + * @param ChameleonTemplate $tpl * @throws \MWException */ - public function getHtml(): string { +public function getHtml($tpl = null): string { + if ( !is_null( $tpl ) ) { + $this->setSkinTemplate( $tpl ); + } return $this->buildContentHeader(); } diff --git a/src/Components/FooterIcons.php b/src/Components/FooterIcons.php index 2d5101bb..48e205fa 100644 --- a/src/Components/FooterIcons.php +++ b/src/Components/FooterIcons.php @@ -42,10 +42,14 @@ class FooterIcons extends Component { /** * Builds the HTML code for this component * + * @param ChameleonTemplate $tpl * @return String the HTML code * @throws \MWException */ - public function getHtml() { + public function getHtml($tpl = null) { + if ( !is_null( $tpl ) ) { + $this->setSkinTemplate( $tpl ); + } return $this->indent() . '' . IdRegistry::getRegistry()->element( 'div', diff --git a/src/Components/FooterInfo.php b/src/Components/FooterInfo.php index db3a6daa..757fe1ac 100644 --- a/src/Components/FooterInfo.php +++ b/src/Components/FooterInfo.php @@ -46,10 +46,14 @@ class FooterInfo extends Component { /** * Builds the HTML code for this component * + * @param ChameleonTemplate $tpl * @return String the HTML code * @throws \MWException */ - public function getHtml() { + public function getHtml($tpl = null) { + if ( !is_null( $tpl ) ) { + $this->setSkinTemplate( $tpl ); + } return $this->indent() . '' . IdRegistry::getRegistry()->element( 'div', diff --git a/src/Components/FooterPlaces.php b/src/Components/FooterPlaces.php index 6cff29e7..738f6e1e 100644 --- a/src/Components/FooterPlaces.php +++ b/src/Components/FooterPlaces.php @@ -42,10 +42,14 @@ class FooterPlaces extends Component { /** * Builds the HTML code for this component * + * @param ChameleonTemplate $tpl * @return String the HTML code * @throws \MWException */ - public function getHtml() { + public function getHtml($tpl = null) { + if ( !is_null( $tpl ) ) { + $this->setSkinTemplate( $tpl ); + } return $this->indent() . '' . IdRegistry::getRegistry()->element( 'div', diff --git a/src/Components/Html.php b/src/Components/Html.php index 196a01f5..4e79ffd7 100644 --- a/src/Components/Html.php +++ b/src/Components/Html.php @@ -40,9 +40,13 @@ class Html extends Component { /** * Builds the HTML code for the main container * + * @param ChameleonTemplate $tpl * @return String the HTML code */ - public function getHtml() { + public function getHtml($tpl = null) { + if ( !is_null( $tpl ) ) { + $this->setSkinTemplate( $tpl ); + } $ret = ''; if ( $this->getDomElement() !== null ) { diff --git a/src/Components/Indicators.php b/src/Components/Indicators.php index 84dad004..5ebe7b86 100644 --- a/src/Components/Indicators.php +++ b/src/Components/Indicators.php @@ -39,9 +39,13 @@ class Indicators extends Component { /** * @inheritDoc + * @param ChameleonTemplate $tpl * @throws \MWException */ - public function getHtml(): string { + public function getHtml($tpl = null): string { + if ( !is_null( $tpl ) ) { + $this->setSkinTemplate( $tpl ); + } $idRegistry = IdRegistry::getRegistry(); return $idRegistry->element( 'div', [ 'id' => 'mw-indicators', diff --git a/src/Components/Logo.php b/src/Components/Logo.php index e9571201..530ab7a1 100644 --- a/src/Components/Logo.php +++ b/src/Components/Logo.php @@ -43,10 +43,14 @@ class Logo extends Component { /** * Builds the HTML code for this component * + * @param ChameleonTemplate $tpl * @return String the HTML code * @throws \MWException */ - public function getHtml() { + public function getHtml($tpl = null) { + if ( !is_null( $tpl ) ) { + $this->setSkinTemplate( $tpl ); + } $logo = $this->indent( 1 ) . $this->getLogo(); return $this->indent( -1 ) . '' . diff --git a/src/Components/MainContent.php b/src/Components/MainContent.php index c5311ceb..facb4041 100644 --- a/src/Components/MainContent.php +++ b/src/Components/MainContent.php @@ -44,10 +44,14 @@ class MainContent extends Component { /** * Builds the HTML code for this component * + * @param ChameleonTemplate $tpl * @return String the HTML code * @throws \MWException */ - public function getHtml() { + public function getHtml($tpl = null) { + if ( !is_null( $tpl ) ) { + $this->setSkinTemplate( $tpl ); + } $idRegistry = IdRegistry::getRegistry(); $topAnchor = $idRegistry->element( 'a', [ 'id' => 'top' ] ); diff --git a/src/Components/Menu.php b/src/Components/Menu.php index 965d2b86..00cf53f4 100644 --- a/src/Components/Menu.php +++ b/src/Components/Menu.php @@ -41,10 +41,14 @@ class Menu extends Component { /** * Builds the HTML code for this component * + * @param ChameleonTemplate $tpl * @return String the HTML code * @throws \MWException */ - public function getHtml() { + public function getHtml($tpl = null) { + if ( !is_null( $tpl ) ) { + $this->setSkinTemplate( $tpl ); + } if ( $this->getDomElement() === null ) { return ''; } diff --git a/src/Components/Message.php b/src/Components/Message.php index 48e3178e..07c4f12f 100644 --- a/src/Components/Message.php +++ b/src/Components/Message.php @@ -40,9 +40,13 @@ class Message extends Component { /** * Builds the HTML code for this component * + * @param ChameleonTemplate $tpl * @return String the HTML code */ - public function getHtml() { + public function getHtml($tpl = null) { + if ( !is_null( $tpl ) ) { + $this->setSkinTemplate( $tpl ); + } $name = $this->getAttribute( 'name' ); if ( !empty( $name ) ) { return $this->getSkinTemplate()->getMsg( $name )->parse(); diff --git a/src/Components/Modifications/Modification.php b/src/Components/Modifications/Modification.php index 53227711..db423924 100644 --- a/src/Components/Modifications/Modification.php +++ b/src/Components/Modifications/Modification.php @@ -163,9 +163,13 @@ public function getDomElement() { /** * Builds the HTML code for this component * + * @param ChameleonTemplate $tpl * @return String the HTML code */ - public function getHtml() { + public function getHtml($tpl = null) { + if ( !is_null( $tpl ) ) { + $this->setSkinTemplate( $tpl ); + } $this->applyModification(); return $this->getComponent()->getHtml(); } diff --git a/src/Components/NavMenu.php b/src/Components/NavMenu.php index f6b8bd93..edf76f75 100644 --- a/src/Components/NavMenu.php +++ b/src/Components/NavMenu.php @@ -45,10 +45,14 @@ class NavMenu extends Component { /** * Builds the HTML code for this component * + * @param ChameleonTemplate $tpl * @return string the HTML code * @throws \MWException */ - public function getHtml() { + public function getHtml($tpl = null) { + if ( !is_null( $tpl ) ) { + $this->setSkinTemplate( $tpl ); + } $ret = ''; $sidebar = $this->getSkinTemplate()->getSidebar( diff --git a/src/Components/NavbarHorizontal.php b/src/Components/NavbarHorizontal.php index 38c70e41..e9343577 100644 --- a/src/Components/NavbarHorizontal.php +++ b/src/Components/NavbarHorizontal.php @@ -51,10 +51,14 @@ class NavbarHorizontal extends Component { /** * Builds the HTML code for this component * + * @param ChameleonTemplate $tpl * @return String the HTML code * @throws \MWException */ - public function getHtml() { + public function getHtml($tpl = null) { + if ( !is_null( $tpl ) ) { + $this->setSkinTemplate( $tpl ); + } if ( $this->mHtml === null ) { $this->buildHtml(); } diff --git a/src/Components/NavbarHorizontal/LangLinks.php b/src/Components/NavbarHorizontal/LangLinks.php index 6d3c955c..44f7ad20 100644 --- a/src/Components/NavbarHorizontal/LangLinks.php +++ b/src/Components/NavbarHorizontal/LangLinks.php @@ -43,10 +43,14 @@ class LangLinks extends Component { /** * Builds the HTML code for this component * + * @param ChameleonTemplate $tpl * @return String the HTML code * @throws \MWException */ - public function getHtml() { + public function getHtml($tpl = null) { + if ( !is_null( $tpl ) ) { + $this->setSkinTemplate( $tpl ); + } if ( !$this->hasLangLinks() ) { return ''; } diff --git a/src/Components/NavbarHorizontal/Logo.php b/src/Components/NavbarHorizontal/Logo.php index bffff470..c2294ea2 100644 --- a/src/Components/NavbarHorizontal/Logo.php +++ b/src/Components/NavbarHorizontal/Logo.php @@ -41,10 +41,14 @@ class Logo extends Component { /** + * @param ChameleonTemplate $tpl * @return String * @throws \MWException */ - public function getHtml() { + public function getHtml($tpl = null) { + if ( !is_null( $tpl ) ) { + $this->setSkinTemplate( $tpl ); + } $logo = new GenLogo( $this->getSkinTemplate(), $this->getDomElement(), $this->getIndent() ); $logo->addClasses( 'navbar-brand' ); diff --git a/src/Components/NavbarHorizontal/Menu.php b/src/Components/NavbarHorizontal/Menu.php index 6a0a54df..4e49fc07 100644 --- a/src/Components/NavbarHorizontal/Menu.php +++ b/src/Components/NavbarHorizontal/Menu.php @@ -41,10 +41,14 @@ class Menu extends Component { /** + * @param ChameleonTemplate $tpl * @return String * @throws \MWException */ - public function getHtml() { + public function getHtml($tpl = null) { + if ( !is_null( $tpl ) ) { + $this->setSkinTemplate( $tpl ); + } $menu = new GenMenu( $this->getSkinTemplate(), $this->getDomElement(), $this->getIndent() ); return $menu->getHtml(); } diff --git a/src/Components/NavbarHorizontal/NavMenu.php b/src/Components/NavbarHorizontal/NavMenu.php index 5cc13058..77431759 100644 --- a/src/Components/NavbarHorizontal/NavMenu.php +++ b/src/Components/NavbarHorizontal/NavMenu.php @@ -41,10 +41,14 @@ class NavMenu extends Component { /** + * @param ChameleonTemplate $tpl * @return String * @throws \MWException */ - public function getHtml() { + public function getHtml($tpl = null) { + if ( !is_null( $tpl ) ) { + $this->setSkinTemplate( $tpl ); + } $navMenu = new GenNavMenu( $this->getSkinTemplate(), $this->getDomElement(), $this->getIndent() + 1 ); return $navMenu->getHtml(); diff --git a/src/Components/NavbarHorizontal/PageTools.php b/src/Components/NavbarHorizontal/PageTools.php index f7a81342..dcaa844d 100644 --- a/src/Components/NavbarHorizontal/PageTools.php +++ b/src/Components/NavbarHorizontal/PageTools.php @@ -41,11 +41,15 @@ class PageTools extends Component { /** + * @param ChameleonTemplate $tpl * @return string * @throws \ConfigException * @throws \MWException */ - public function getHtml() { + public function getHtml($tpl = null) { + if ( !is_null( $tpl ) ) { + $this->setSkinTemplate( $tpl ); + } $pageTools = $this->createGenericPageTools(); $this->indent( 1 ); diff --git a/src/Components/NavbarHorizontal/PersonalTools.php b/src/Components/NavbarHorizontal/PersonalTools.php index ce1ca19c..e902ad1e 100644 --- a/src/Components/NavbarHorizontal/PersonalTools.php +++ b/src/Components/NavbarHorizontal/PersonalTools.php @@ -58,11 +58,15 @@ class PersonalTools extends Component { protected ?string $avatarUrl = null; /** + * @param ChameleonTemplate $tpl * @return String * @throws \FatalError * @throws \MWException */ - public function getHtml() { + public function getHtml($tpl = null) { + if ( !is_null( $tpl ) ) { + $this->setSkinTemplate( $tpl ); + } $tools = $this->getSkinTemplate()->getPersonalTools(); $this->setUserAvatar(); diff --git a/src/Components/NavbarHorizontal/PersonalTools.php.orig b/src/Components/NavbarHorizontal/PersonalTools.php.orig new file mode 100644 index 00000000..64d44f57 --- /dev/null +++ b/src/Components/NavbarHorizontal/PersonalTools.php.orig @@ -0,0 +1,324 @@ +. + * + * @file + * @ingroup Skins + */ + +namespace Skins\Chameleon\Components\NavbarHorizontal; + +use MediaWiki\MediaWikiServices; +use Skins\Chameleon\Components\Component; +use Skins\Chameleon\IdRegistry; + +/** + * The NavbarHorizontal\PersonalTools class. + * + * Provides a PersonalTools component to be included in a NavbarHorizontal component. + * + * @author Stephan Gambke + * @since 1.6 + * @ingroup Skins + */ +class PersonalTools extends Component { + + private const ECHO_LINK_KEYS = [ 'notifications-alert', 'notifications-notice' ]; + private const ATTR_SHOW_ECHO = 'showEcho'; + private const SHOW_ECHO_ICONS = 'icons'; + private const SHOW_ECHO_LINKS = 'links'; + private const ATTR_SHOW_USER_NAME = 'showUserName'; + private const SHOW_USER_NAME_NONE = 'none'; + private const SHOW_USER_NAME_TRY_REALNAME = 'try-realname'; + private const SHOW_USER_NAME_USERNAME_ONLY = 'username-only'; + // Boolean values for showUserName deprecated since Chameleon 4.2.0: + private const SHOW_USER_NAME_NO = 'no'; + private const SHOW_USER_NAME_YES = 'yes'; + private const ATTR_PROMOTE_LONE_ITEMS = 'promoteLoneItems'; + private const ATTR_SHOW_USER_AVATAR = 'showUserAvatar'; + + protected ?string $avatarUrl = null; + + /** + * @return String + * @throws \FatalError + * @throws \MWException + */ + public function getHtml($tpl = null) { + if ( !is_null( $tpl ) ) { + $this->setSkinTemplate( $tpl ); + } + $tools = $this->getSkinTemplate()->getPersonalTools(); + + $this->setUserAvatar(); + + // Flatten classes to avoid MW bug: https://phabricator.wikimedia.org/T262160 + // NB: This bug is finally fixed in MW >=1.36. + foreach ( $tools as $key => $item ) { + if ( !empty( $item['links'][0]['class'] ) && is_array( $item['links'][0]['class'] ) ) { + $tools[$key]['links'][0]['class'] = implode( ' ', $item['links'][0]['class'] ); + } + } + + // start personal tools element + $echoHtml = ''; + if ( $this->getShowEcho() === self::SHOW_ECHO_ICONS ) { + $echoHtml = $this->indent() . $this->getEchoIcons( $tools ); + } + + if ( count( $tools ) == 1 ) { + $promotableItems = + array_map( 'trim', + explode( ';', $this->getAttribute( self::ATTR_PROMOTE_LONE_ITEMS ) ) ); + $loneKey = array_key_first( $tools ); + if ( in_array( $loneKey, $promotableItems, true ) ) { + $item = $tools[$loneKey]; + return $echoHtml . + $this->indent() . '' . + $this->indent() . ''; + } + } + + return $echoHtml . + $this->indent() . '' . + $this->indent() . ''; + } + + /** + * @return string + * @throws \FatalError + * @throws \MWException + */ + protected function getNewtalkNotifier() { + $user = $this->getSkinTemplate()->getSkin()->getUser(); + + $newMessagesAlert = $this->getSkinTemplate()->getMsg( 'chameleon-newmessages' )->text(); + + if ( empty( $this->getSkinTemplate()->data[ 'newtalk' ] ) ) { + return ''; + } + + $talkClass = $user->isRegistered() ? 'pt-mytalk' : 'pt-anontalk'; + + $newtalkNotifier = $this->indent( 1 ) . ''; + $this->indent( -1 ); + + return $newtalkNotifier; + } + + /** + * @return string + * @throws \FatalError + * @throws \MWException + */ + protected function getUserName() { + $user = $this->getSkinTemplate()->getSkin()->getUser(); + if ( $user->isRegistered() ) { + $showUserName = $this->getAttribute( self::ATTR_SHOW_USER_NAME ); + if ( ( $showUserName == self::SHOW_USER_NAME_TRY_REALNAME ) || + ( $showUserName == self::SHOW_USER_NAME_YES ) ) { + $username = !empty( $user->getRealName() ) ? $user->getRealName() : $user->getName(); + return '' . htmlspecialchars( $username ) . ''; + } elseif ( $showUserName == self::SHOW_USER_NAME_USERNAME_ONLY ) { + return '' . htmlspecialchars( $user->getName() ) . ''; + } + } + return ''; + } + + /** + * @param array $tools + * + * @return string + * @throws \MWException + */ + protected function getToolsHtml( $tools ) { + $this->indent( 1 ); + $ret = ''; + + // add personal tools (links to user page, user talk, prefs, ...) + foreach ( $tools as $key => $item ) { + if ( in_array( $key, self::ECHO_LINK_KEYS ) ) { + $showEcho = $this->getShowEcho(); + if ( $showEcho === self::SHOW_ECHO_LINKS ) { + // Remove Echo classes to render as a link + unset( $item['links'][0]['class'] ); + } elseif ( $showEcho === self::SHOW_ECHO_ICONS ) { + // Icons will be rendered elsewhere + continue; + } + } + + if ( isset( $item['id'] ) ) { + $ret .= $this->indent() . $this->getSkinTemplate()->makeListItem( $key, $item, + [ 'tag' => 'div', 'link-class' => $item['id'] ] ); + } else { + $ret .= $this->indent() . $this->getSkinTemplate()->makeListItem( $key, $item, + [ 'tag' => 'div' ] ); + } + } + + $this->indent( -1 ); + return $ret; + } + + /** + * @param array $tools + * + * @return string + * @throws \MWException + */ + protected function getEchoIcons( $tools ) { + $items = ''; + + foreach ( $tools as $key => $item ) { + if ( in_array( $key, self::ECHO_LINK_KEYS ) ) { + $items .= $this->indent() . + $this->getSkinTemplate()->makeListItem( $key, $item ); + } + } + + if ( empty( $items ) ) { + return ''; + } + + return '' . + ''; + } + + + /** + * @return string + * @throws \FatalError + * @throws \MWException + */ + protected function getDropdownToggle(): string { + $user = $this->getSkinTemplate()->getSkin()->getUser(); + + if ( $user->isRegistered() ) { + $toolsClass = 'navbar-userloggedin' . ( !$this->avatarUrl ? '' : '-avatar' ); + $toolsLinkText = $this->getSkinTemplate()->getMsg( 'chameleon-loggedin' )-> + params( $user->getName() )->text(); + + } else { + $toolsClass = 'navbar-usernotloggedin'; + $toolsLinkText = $this->getSkinTemplate()->getMsg( 'chameleon-notloggedin' )->text(); + } + + // TODO Rename '...LinkText' to '...LinkTitle' in both the hook and variable. + MediaWikiServices::getInstance()->getHookContainer()->run( 'ChameleonNavbarHorizontalPersonalToolsLinkText', [ &$toolsLinkText, + $this->getSkin() ] ); + + $newtalkNotifierHtml = $this->getNewtalkNotifier(); + $userNameHtml = $this->getUserName(); + + MediaWikiServices::getInstance()->getHookContainer()->run( 'ChameleonNavbarHorizontalPersonalToolsLinkInnerHtml', + [ &$newtalkNotifierHtml, &$userNameHtml, $this ] ); + + $this->indent( 1 ); + + $attr = [ + 'class' => $toolsClass, + 'href' => '#', 'data-toggle' => 'dropdown', 'data-boundary' => 'viewport', + 'title' => $toolsLinkText + ]; + + if ( $this->avatarUrl ) { + $attr['style'] = "background-image:url('$this->avatarUrl')"; + } + + $dropdownToggle = IdRegistry::getRegistry()->element( 'a', $attr, $newtalkNotifierHtml . $userNameHtml, + $this->indent() ); + + $this->indent( -1 ); + + return $dropdownToggle; + } + + private function setUserAvatar(): void { + if ( !$this->shouldShowUserAvatar() ) { + return; + } + + $user = $this->getSkinTemplate()->getSkin()->getUser(); + if ( !$user->isRegistered() ) { + return; + } + + // let users of the skin set an avatar url by some + // other criteria. e.g. SMW could use + // \SMW\DIProperty::newFromUserLabel( 'User image' ) + if ( !MediaWikiServices::getInstance()->getHookContainer()->run( 'ChameleonNavbarHorizontalPersonalToolsAvatarUrl', + [ &$this->avatarUrl, $this->getSkin() ] ) ) { + return; + } + + // retrieve an image with the same name + // of the user with some common extension + $imageExt = [ 'png', 'jpg', 'jpeg' ]; + $imagePage = null; + $username = $user->getName(); + foreach ( $imageExt as $ext ) { + $title = \Title::makeTitleSafe( NS_FILE, "$username.$ext" ); + if ( $title && $title->isKnown() ) { + $imagePage = new \WikiFilePage( $title ); + break; + } + } + if ( !$imagePage ) { + return; + } + + $this->avatarUrl = $imagePage->getFile()->createThumb( 41, 41 ); + } + + private function shouldShowUserAvatar(): bool { + return filter_var( $this->getAttribute( self::ATTR_SHOW_USER_AVATAR ), FILTER_VALIDATE_BOOLEAN ); + } + + /** + * @return string + */ + protected function getShowEcho() { + return $this->getAttribute( self::ATTR_SHOW_ECHO, self::SHOW_ECHO_ICONS ); + } + +} diff --git a/src/Components/NavbarHorizontal/SearchBar.php b/src/Components/NavbarHorizontal/SearchBar.php index 03201725..c69d94cd 100644 --- a/src/Components/NavbarHorizontal/SearchBar.php +++ b/src/Components/NavbarHorizontal/SearchBar.php @@ -41,9 +41,13 @@ class SearchBar extends Component { /** + * @param ChameleonTemplate $tpl * @return String */ - public function getHtml() { + public function getHtml($tpl = null) { + if ( !is_null( $tpl ) ) { + $this->setSkinTemplate( $tpl ); + } $search = new GenericSearchBar( $this->getSkinTemplate(), $this->getDomElement(), $this->getIndent() ); $search->addClasses( 'navbar-form' ); diff --git a/src/Components/NavbarHorizontal/Toolbox.php b/src/Components/NavbarHorizontal/Toolbox.php index 2adc0ff0..5fe6632a 100644 --- a/src/Components/NavbarHorizontal/Toolbox.php +++ b/src/Components/NavbarHorizontal/Toolbox.php @@ -46,10 +46,14 @@ class Toolbox extends Component { /** * Builds the HTML code for this component * + * @param ChameleonTemplate $tpl * @return String the HTML code * @throws \MWException */ - public function getHtml() { + public function getHtml($tpl = null) { + if ( !is_null( $tpl ) ) { + $this->setSkinTemplate( $tpl ); + } $introComment = $this->indent() . ''; if ( filter_var( $this->getAttribute( 'flatten' ), FILTER_VALIDATE_BOOLEAN ) ) { diff --git a/src/Components/NewtalkNotifier.php b/src/Components/NewtalkNotifier.php index 135ec8e2..954cf015 100644 --- a/src/Components/NewtalkNotifier.php +++ b/src/Components/NewtalkNotifier.php @@ -40,10 +40,14 @@ class NewtalkNotifier extends Component { /** * Builds the HTML code for this component * + * @param ChameleonTemplate $tpl * @return String the HTML code * @throws \MWException */ - public function getHtml() { + public function getHtml($tpl = null) { + if ( !is_null( $tpl ) ) { + $this->setSkinTemplate( $tpl ); + } $data = $this->getSkinTemplate()->data; if ( array_key_exists( 'newtalk', $data ) && $data[ 'newtalk' ] ) { diff --git a/src/Components/PageTools.php b/src/Components/PageTools.php index f2b7c730..8c1f2296 100644 --- a/src/Components/PageTools.php +++ b/src/Components/PageTools.php @@ -65,11 +65,15 @@ public function __construct( ChameleonTemplate $template, \DOMElement $domElemen /** * Builds the HTML code for this component * + * @param ChameleonTemplate $tpl * @return string the HTML code * @throws \ConfigException * @throws \MWException */ - public function getHtml() { + public function getHtml($tpl = null) { + if ( !is_null( $tpl ) ) { + $this->setSkinTemplate( $tpl ); + } $toolGroups = $this->getToolGroups(); if ( $toolGroups === [] ) { diff --git a/src/Components/PersonalTools.php b/src/Components/PersonalTools.php index 1d913dc7..66667880 100644 --- a/src/Components/PersonalTools.php +++ b/src/Components/PersonalTools.php @@ -45,10 +45,14 @@ class PersonalTools extends Component { /** * Builds the HTML code for this component * + * @param ChameleonTemplate $tpl * @return String the HTML code * @throws \MWException */ - public function getHtml() { + public function getHtml($tpl = null) { + if ( !is_null( $tpl ) ) { + $this->setSkinTemplate( $tpl ); + } $ret = $this->indent() . '' . $this->indent() . '
'; diff --git a/src/Components/SearchBar.php b/src/Components/SearchBar.php index 5d52452e..081730ab 100644 --- a/src/Components/SearchBar.php +++ b/src/Components/SearchBar.php @@ -44,10 +44,14 @@ class SearchBar extends Component { /** * Builds the HTML code for this component * + * @param ChameleonTemplate $tpl * @return string * @throws \MWException */ - public function getHtml() { + public function getHtml($tpl = null) { + if ( !is_null( $tpl ) ) { + $this->setSkinTemplate( $tpl ); + } $attribsSearchFormWrapper = \Html::expandAttributes( [ 'id' => IdRegistry::getRegistry()->getId( 'p-search' ), 'class' => 'p-search ' . $this->getClassString(), diff --git a/src/Components/Silent.php b/src/Components/Silent.php index b432d30b..8853e281 100644 --- a/src/Components/Silent.php +++ b/src/Components/Silent.php @@ -42,9 +42,13 @@ class Silent extends Component { /** * Builds the HTML code for this component * + * @param ChameleonTemplate $tpl * @return String the HTML code */ - public function getHtml() { + public function getHtml($tpl = null) { + if ( !is_null( $tpl ) ) { + $this->setSkinTemplate( $tpl ); + } return ''; } } diff --git a/src/Components/SiteNotice.php b/src/Components/SiteNotice.php index 28e65873..a539de13 100644 --- a/src/Components/SiteNotice.php +++ b/src/Components/SiteNotice.php @@ -40,9 +40,13 @@ class SiteNotice extends Component { /** * Builds the HTML code for this component * + * @param ChameleonTemplate $tpl * @return String the HTML code */ - public function getHtml() { + public function getHtml($tpl = null) { + if ( !is_null( $tpl ) ) { + $this->setSkinTemplate( $tpl ); + } $data = $this->getSkinTemplate()->data; if ( array_key_exists( 'sitenotice', $data ) && $data[ 'sitenotice' ] ) { diff --git a/src/Components/Structure.php b/src/Components/Structure.php index 7c8a4df0..c13e5ebc 100644 --- a/src/Components/Structure.php +++ b/src/Components/Structure.php @@ -44,14 +44,15 @@ class Structure extends Component { /** * Builds the HTML code for the component * + * @param ChameleonTemplate $tpl * @return string the HTML code * @throws \MWException */ - public function getHtml() { + public function getHtml($tpl = null) { $ret = ''; foreach ( $this->getSubcomponents() as $component ) { - $ret .= $component->getHtml(); + $ret .= $component->getHtml( $tpl ); } return $ret; diff --git a/src/Components/Toc.php b/src/Components/Toc.php index 28a4927b..804817ce 100644 --- a/src/Components/Toc.php +++ b/src/Components/Toc.php @@ -39,8 +39,12 @@ class Toc extends Component { /** * @inheritDoc + * @param ChameleonTemplate $tpl */ - public function getHtml(): string { +public function getHtml($tpl = null): string { + if ( !is_null( $tpl ) ) { + $this->setSkinTemplate( $tpl ); + } $html = $this->extractTocHtml(); if ( $html === '' ) { From 931b152b2bcb518cb3f5769ee634d6e6c402d23d Mon Sep 17 00:00:00 2001 From: WouterRademaker Date: Mon, 5 Aug 2024 14:31:25 +0200 Subject: [PATCH 2/3] not needed --- .../NavbarHorizontal/PersonalTools.php.orig | 324 ------------------ 1 file changed, 324 deletions(-) delete mode 100644 src/Components/NavbarHorizontal/PersonalTools.php.orig diff --git a/src/Components/NavbarHorizontal/PersonalTools.php.orig b/src/Components/NavbarHorizontal/PersonalTools.php.orig deleted file mode 100644 index 64d44f57..00000000 --- a/src/Components/NavbarHorizontal/PersonalTools.php.orig +++ /dev/null @@ -1,324 +0,0 @@ -. - * - * @file - * @ingroup Skins - */ - -namespace Skins\Chameleon\Components\NavbarHorizontal; - -use MediaWiki\MediaWikiServices; -use Skins\Chameleon\Components\Component; -use Skins\Chameleon\IdRegistry; - -/** - * The NavbarHorizontal\PersonalTools class. - * - * Provides a PersonalTools component to be included in a NavbarHorizontal component. - * - * @author Stephan Gambke - * @since 1.6 - * @ingroup Skins - */ -class PersonalTools extends Component { - - private const ECHO_LINK_KEYS = [ 'notifications-alert', 'notifications-notice' ]; - private const ATTR_SHOW_ECHO = 'showEcho'; - private const SHOW_ECHO_ICONS = 'icons'; - private const SHOW_ECHO_LINKS = 'links'; - private const ATTR_SHOW_USER_NAME = 'showUserName'; - private const SHOW_USER_NAME_NONE = 'none'; - private const SHOW_USER_NAME_TRY_REALNAME = 'try-realname'; - private const SHOW_USER_NAME_USERNAME_ONLY = 'username-only'; - // Boolean values for showUserName deprecated since Chameleon 4.2.0: - private const SHOW_USER_NAME_NO = 'no'; - private const SHOW_USER_NAME_YES = 'yes'; - private const ATTR_PROMOTE_LONE_ITEMS = 'promoteLoneItems'; - private const ATTR_SHOW_USER_AVATAR = 'showUserAvatar'; - - protected ?string $avatarUrl = null; - - /** - * @return String - * @throws \FatalError - * @throws \MWException - */ - public function getHtml($tpl = null) { - if ( !is_null( $tpl ) ) { - $this->setSkinTemplate( $tpl ); - } - $tools = $this->getSkinTemplate()->getPersonalTools(); - - $this->setUserAvatar(); - - // Flatten classes to avoid MW bug: https://phabricator.wikimedia.org/T262160 - // NB: This bug is finally fixed in MW >=1.36. - foreach ( $tools as $key => $item ) { - if ( !empty( $item['links'][0]['class'] ) && is_array( $item['links'][0]['class'] ) ) { - $tools[$key]['links'][0]['class'] = implode( ' ', $item['links'][0]['class'] ); - } - } - - // start personal tools element - $echoHtml = ''; - if ( $this->getShowEcho() === self::SHOW_ECHO_ICONS ) { - $echoHtml = $this->indent() . $this->getEchoIcons( $tools ); - } - - if ( count( $tools ) == 1 ) { - $promotableItems = - array_map( 'trim', - explode( ';', $this->getAttribute( self::ATTR_PROMOTE_LONE_ITEMS ) ) ); - $loneKey = array_key_first( $tools ); - if ( in_array( $loneKey, $promotableItems, true ) ) { - $item = $tools[$loneKey]; - return $echoHtml . - $this->indent() . '' . - $this->indent() . ''; - } - } - - return $echoHtml . - $this->indent() . '' . - $this->indent() . ''; - } - - /** - * @return string - * @throws \FatalError - * @throws \MWException - */ - protected function getNewtalkNotifier() { - $user = $this->getSkinTemplate()->getSkin()->getUser(); - - $newMessagesAlert = $this->getSkinTemplate()->getMsg( 'chameleon-newmessages' )->text(); - - if ( empty( $this->getSkinTemplate()->data[ 'newtalk' ] ) ) { - return ''; - } - - $talkClass = $user->isRegistered() ? 'pt-mytalk' : 'pt-anontalk'; - - $newtalkNotifier = $this->indent( 1 ) . ''; - $this->indent( -1 ); - - return $newtalkNotifier; - } - - /** - * @return string - * @throws \FatalError - * @throws \MWException - */ - protected function getUserName() { - $user = $this->getSkinTemplate()->getSkin()->getUser(); - if ( $user->isRegistered() ) { - $showUserName = $this->getAttribute( self::ATTR_SHOW_USER_NAME ); - if ( ( $showUserName == self::SHOW_USER_NAME_TRY_REALNAME ) || - ( $showUserName == self::SHOW_USER_NAME_YES ) ) { - $username = !empty( $user->getRealName() ) ? $user->getRealName() : $user->getName(); - return '' . htmlspecialchars( $username ) . ''; - } elseif ( $showUserName == self::SHOW_USER_NAME_USERNAME_ONLY ) { - return '' . htmlspecialchars( $user->getName() ) . ''; - } - } - return ''; - } - - /** - * @param array $tools - * - * @return string - * @throws \MWException - */ - protected function getToolsHtml( $tools ) { - $this->indent( 1 ); - $ret = ''; - - // add personal tools (links to user page, user talk, prefs, ...) - foreach ( $tools as $key => $item ) { - if ( in_array( $key, self::ECHO_LINK_KEYS ) ) { - $showEcho = $this->getShowEcho(); - if ( $showEcho === self::SHOW_ECHO_LINKS ) { - // Remove Echo classes to render as a link - unset( $item['links'][0]['class'] ); - } elseif ( $showEcho === self::SHOW_ECHO_ICONS ) { - // Icons will be rendered elsewhere - continue; - } - } - - if ( isset( $item['id'] ) ) { - $ret .= $this->indent() . $this->getSkinTemplate()->makeListItem( $key, $item, - [ 'tag' => 'div', 'link-class' => $item['id'] ] ); - } else { - $ret .= $this->indent() . $this->getSkinTemplate()->makeListItem( $key, $item, - [ 'tag' => 'div' ] ); - } - } - - $this->indent( -1 ); - return $ret; - } - - /** - * @param array $tools - * - * @return string - * @throws \MWException - */ - protected function getEchoIcons( $tools ) { - $items = ''; - - foreach ( $tools as $key => $item ) { - if ( in_array( $key, self::ECHO_LINK_KEYS ) ) { - $items .= $this->indent() . - $this->getSkinTemplate()->makeListItem( $key, $item ); - } - } - - if ( empty( $items ) ) { - return ''; - } - - return '' . - ''; - } - - - /** - * @return string - * @throws \FatalError - * @throws \MWException - */ - protected function getDropdownToggle(): string { - $user = $this->getSkinTemplate()->getSkin()->getUser(); - - if ( $user->isRegistered() ) { - $toolsClass = 'navbar-userloggedin' . ( !$this->avatarUrl ? '' : '-avatar' ); - $toolsLinkText = $this->getSkinTemplate()->getMsg( 'chameleon-loggedin' )-> - params( $user->getName() )->text(); - - } else { - $toolsClass = 'navbar-usernotloggedin'; - $toolsLinkText = $this->getSkinTemplate()->getMsg( 'chameleon-notloggedin' )->text(); - } - - // TODO Rename '...LinkText' to '...LinkTitle' in both the hook and variable. - MediaWikiServices::getInstance()->getHookContainer()->run( 'ChameleonNavbarHorizontalPersonalToolsLinkText', [ &$toolsLinkText, - $this->getSkin() ] ); - - $newtalkNotifierHtml = $this->getNewtalkNotifier(); - $userNameHtml = $this->getUserName(); - - MediaWikiServices::getInstance()->getHookContainer()->run( 'ChameleonNavbarHorizontalPersonalToolsLinkInnerHtml', - [ &$newtalkNotifierHtml, &$userNameHtml, $this ] ); - - $this->indent( 1 ); - - $attr = [ - 'class' => $toolsClass, - 'href' => '#', 'data-toggle' => 'dropdown', 'data-boundary' => 'viewport', - 'title' => $toolsLinkText - ]; - - if ( $this->avatarUrl ) { - $attr['style'] = "background-image:url('$this->avatarUrl')"; - } - - $dropdownToggle = IdRegistry::getRegistry()->element( 'a', $attr, $newtalkNotifierHtml . $userNameHtml, - $this->indent() ); - - $this->indent( -1 ); - - return $dropdownToggle; - } - - private function setUserAvatar(): void { - if ( !$this->shouldShowUserAvatar() ) { - return; - } - - $user = $this->getSkinTemplate()->getSkin()->getUser(); - if ( !$user->isRegistered() ) { - return; - } - - // let users of the skin set an avatar url by some - // other criteria. e.g. SMW could use - // \SMW\DIProperty::newFromUserLabel( 'User image' ) - if ( !MediaWikiServices::getInstance()->getHookContainer()->run( 'ChameleonNavbarHorizontalPersonalToolsAvatarUrl', - [ &$this->avatarUrl, $this->getSkin() ] ) ) { - return; - } - - // retrieve an image with the same name - // of the user with some common extension - $imageExt = [ 'png', 'jpg', 'jpeg' ]; - $imagePage = null; - $username = $user->getName(); - foreach ( $imageExt as $ext ) { - $title = \Title::makeTitleSafe( NS_FILE, "$username.$ext" ); - if ( $title && $title->isKnown() ) { - $imagePage = new \WikiFilePage( $title ); - break; - } - } - if ( !$imagePage ) { - return; - } - - $this->avatarUrl = $imagePage->getFile()->createThumb( 41, 41 ); - } - - private function shouldShowUserAvatar(): bool { - return filter_var( $this->getAttribute( self::ATTR_SHOW_USER_AVATAR ), FILTER_VALIDATE_BOOLEAN ); - } - - /** - * @return string - */ - protected function getShowEcho() { - return $this->getAttribute( self::ATTR_SHOW_ECHO, self::SHOW_ECHO_ICONS ); - } - -} From 27812858c9c03c7c19796d57afd7a2d8048ae78f Mon Sep 17 00:00:00 2001 From: WouterRademaker Date: Mon, 5 Aug 2024 16:08:14 +0200 Subject: [PATCH 3/3] some more icons --- resources/styles/_variables.scss | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/resources/styles/_variables.scss b/resources/styles/_variables.scss index 2cdb4cf6..dbf22aac 100644 --- a/resources/styles/_variables.scss +++ b/resources/styles/_variables.scss @@ -83,6 +83,7 @@ $cmln-icons: map-merge(( navbar-more-tools: fas fa-ellipsis-h, navbar-usernotloggedin: fas fa-user, navbar-userloggedin: fas fa-user, + ca-addsection: fas fa-plus, ca-cargo-purge: fas fa-redo, ca-delete: fas fa-trash-alt, ca-edit: far fa-edit, @@ -99,6 +100,7 @@ $cmln-icons: map-merge(( ca-nstab-mediawiki: fas fa-cogs, ca-nstab-project: fas fa-project-diagram, ca-nstab-rule: fas fa-ruler, + ca-nstab-smw: fas fa-boxes, ca-nstab-special: fas fa-cogs, ca-nstab-template: fas fa-stamp, ca-nstab-user: far fa-user, @@ -106,10 +108,12 @@ $cmln-icons: map-merge(( ca-protect: fas fa-lock, ca-purge: fas fa-redo, ca-recreatedata: fas fa-database, + ca-semantic_edit: fas fa-pen-fancy, ca-talk: far fa-comments, ca-unprotect: fas fa-lock, ca-unwatch: far fa-eye-slash, ca-ve-edit: far fa-edit, + ca-view-foreign: far fa-images, ca-viewsource: fas fa-code, ca-watch: far fa-eye, feedlink: fas fa-rss, @@ -121,6 +125,7 @@ $cmln-icons: map-merge(( n-List-of-files-with-duplicates: fas fa-check-double, n-Slack: fab fa-slack, n-Uncategorized-files: fas fa-object-ungroup, + n-contributionscores: fas fa-user-tag, n-help-mediawiki: fas fa-question, n-help: fas fa-question, n-mainpage-description: fas fa-home, @@ -133,6 +138,8 @@ $cmln-icons: map-merge(( n-recentchanges: fas fa-backward, n-upload: fas fa-upload, p-lang-toggle: fas fa-language, + p-navigation-toggle: far fa-compass, + p-Page-Properties-toggle: fas fa-shapes, p-tb-toggle: fas fa-toolbox, pt-anoncontribs: fas fa-question, // FIXME: Pers tools: Anon contribs pt-anontalk: fas fa-comments,