From f8e5ad7cda14dba65de30fb3d58ba828daeadb2d Mon Sep 17 00:00:00 2001 From: Jon Robson Date: Fri, 27 May 2022 17:40:24 -0700 Subject: [PATCH] Expand the hooks SkinJSON surfaces and add tooltips and links As suggested in https://github.com/jdlrobson/skins.wmflabs.org/issues/13 Change-Id: Iaa96e74fda83fc1c15be2770d0ff9187603a1c55 --- SkinJSON.php | 73 +++++++++++++++++++++++++++++++++++++------------ skin.json | 2 ++ skinValidate.js | 4 +-- 3 files changed, 60 insertions(+), 19 deletions(-) diff --git a/SkinJSON.php b/SkinJSON.php index 22f569d..681782d 100644 --- a/SkinJSON.php +++ b/SkinJSON.php @@ -46,9 +46,7 @@ public static function onSiteNoticeAfter( &$siteNotice, $skin ) { $empty = strlen( $siteNotice ) === 0; $config = $skin->getConfig(); if ( $config->get( 'SkinJSONValidate' ) ) { - $siteNotice .= Html::element( 'div', [ - 'class' => 'skin-json-banner-validation-element skin-json-validation-element', - ], '' ); + $siteNotice .= self::hookTestElement( 'SiteNoticeAfter', $config, false ); return $empty; } } @@ -61,6 +59,12 @@ public static function onRegistration() { ); } + public static function onOutputPageBodyAttributes( $out, $sk, &$bodyAttrs ): void { + if ( !$out->getConfig()->get( 'SkinJSONExtensionHints' ) ) { + $bodyAttrs['class'] .= ' skin-json-hints-hide'; + } + } + /** * Forwards OutputPageBeforeHTML hook modifications to the template * This makes SkinJSON work with the MobileFrontend ContentProvider proxy. @@ -72,6 +76,9 @@ public static function onOutputPageBeforeHTML( $out, &$html ) { $out->addModuleStyles( [ 'skins.skinjson.debug.styles' ] ); } if ( $config->get( 'SkinJSONValidate' ) ) { + $out->addSubtitle( + self::hookTestElement( 'OutputPageBeforeHTML', $config, false, 'Call addSubtitle on OutputPage' ) + ); $out->addJsConfigVars( [ 'wgSkinJSONValidate' => [ 'wgLogos' => ResourceLoaderSkinModule::getAvailableLogos( @@ -82,7 +89,10 @@ public static function onOutputPageBeforeHTML( $out, &$html ) { $out->addHTML( implode( '', [ '' ] ) ); @@ -94,28 +104,57 @@ public static function onOutputPageBeforeHTML( $out, &$html ) { } } - private static function hookTestElement( string $hook, Config $config ) { + private static function hookTestData( string $hook, Config $config, $inline = true, $note = '' ) { + $hookUrl = '//www.mediawiki.org/wiki/Manual:Hooks/' . $hook; if ( $config->get( 'SkinJSONValidate' ) ) { - return Html::element( 'div', [ - 'class' => 'skin-json-hook-validation-element skin-json-validation-element', + $link = Html::element( 'a', [ + 'href' => $hookUrl, + 'title' => $note + ], $hook ); + return [ + 'title' => $note, + 'class' => [ + 'skin-json-hook-validation-element', + 'skin-json-hook-validation-element-' . $hook, + 'skin-json-validation-element', + $inline ? 'skin-json-validation-element-inline' : 'skin-json-validation-element-block' + ], + 'html' => $link, 'data-hook' => $hook, - ], '' ); + ]; + } else { + return []; + } + } + + private static function hookTestElement( string $hook, Config $config, $inline = true, $note = '' ) { + if ( $config->get( 'SkinJSONValidate' ) ) { + $data = self::hookTestData( $hook, $config, $inline, $note ); + $link = $data['html']; + unset( $data['html'] ); + return Html::rawElement( 'div', $data, $link ); } else { return ''; } } public static function onSkinAfterPortlet( $skin, $name, &$html ) { - $html .= self::hookTestElement( 'SkinAfterPortlet', $skin->getConfig() ); + $html .= self::hookTestElement( + 'SkinAfterPortlet', + $skin->getConfig(), + // only these ones are inline + in_array( $name, [ 'navigation', 'namespaces', 'views' ] ), + '($name === "' . $name . '")' + ); } public static function onSkinAfterContent( &$html, Skin $skin ) { - $html .= self::hookTestElement( 'SkinAfterContent', $skin->getConfig() ); + $html .= self::hookTestElement( 'SkinAfterContent', $skin->getConfig(), false ); } public static function onSkinAddFooterLinks( Skin $skin, string $key, array &$footerlinks ) { if ( $key === 'places' ) { - $footerlinks['test'] = self::hookTestElement( 'SkinAddFooterLinks', $skin->getConfig() ); + $footerlinks['test'] = self::hookTestElement( 'SkinAddFooterLinks', $skin->getConfig(), true, '($key === places)' ); } } @@ -129,12 +168,12 @@ public static function onSkinTemplateNavigationUniversal( $skin, &$links ) { } public static function onSidebarBeforeOutput( Skin $skin, &$sidebar ) { - $sidebar['navigation']['skin-json-hook-validation-sidebar-item'] = [ - 'class' => [ - 'skin-json-validation-element', - 'skin-json-validation-element-SidebarBeforeOutput' - ], - ]; + $sidebar['navigation']['skin-json-hook-validation-sidebar-item'] = self::hookTestData( + 'SidebarBeforeOutput', + $skin->getConfig(), + true, + '(appending to $sidebar["navigation"])' + ); } private static function isSkinJSONMode( $request ) { diff --git a/skin.json b/skin.json index ae7a793..c7e866f 100644 --- a/skin.json +++ b/skin.json @@ -65,12 +65,14 @@ }, "config": { "SkinJSONTestUser": "", + "SkinJSONExtensionHints": true, "SkinJSONDebug": true, "SkinJSONValidate": true }, "Hooks": { "SiteNoticeAfter": "SkinJSON::onSiteNoticeAfter", "SidebarBeforeOutput": "SkinJSON::onSidebarBeforeOutput", + "OutputPageBodyAttributes": "SkinJSON::onOutputPageBodyAttributes", "OutputPageBeforeHTML": "SkinJSON::onOutputPageBeforeHTML", "RequestContextCreateSkin": "SkinJSON::onRequestContextCreateSkin", "SkinAfterPortlet": "SkinJSON::onSkinAfterPortlet", diff --git a/skinValidate.js b/skinValidate.js index 6966f2b..5ce7534 100644 --- a/skinValidate.js +++ b/skinValidate.js @@ -9,12 +9,12 @@ $(function () { // Value - Condition to check; True -> Pass; False -> Fail const rules = { 'Skin does not show the article': $( '.mw-body-content' ).length > 0, - 'Skin does not support site notices (banners)': $( '.skin-json-banner-validation-element' ).length > 0, + 'Skin does not support site notices (banners)': $( '.skin-json-hook-validation-element-SiteNoticeAfter' ).length > 0, 'Skin is not responsive': $('meta[name="viewport"]').length > 0, 'Search may not support autocomplete': $('.mw-searchInput,#searchInput').length > 0, 'Sidebar may not show main navigation': $( '#n-mainpage-description' ).length !== 0, 'Sidebar may not support extensions': $( - '.skin-json-validation-element-SidebarBeforeOutput' + '.skin-json-hook-validation-element-SidebarBeforeOutput' ).length !== 0 }; const rulesAdvancedUsers = {