diff --git a/Refreshed.php b/Refreshed.php index ba08717..3f38aba 100644 --- a/Refreshed.php +++ b/Refreshed.php @@ -1,65 +1,66 @@ __FILE__, 'name' => 'Refreshed', 'version' => '3.1.0', 'author' => array( 'Adam Carter', 'George Barnick', 'MtMNC', 'ShermanTheMythran', 'Jack Phoenix', 'Drew1200', 'SirComputer', 'Seaside98', 'Codyn329', 'Lewis Cawte' ), 'description' => 'A clean, modern MediaWiki skin with extensive CSS customisability', 'url' => 'https://www.mediawiki.org/wiki/Skin:Refreshed', ); // The first instance must be strtolower()ed so that useskin=refreshed works and // so that it does *not* force an initial capital (i.e. we do NOT want // useskin=Refreshed) and the second instance is used to determine the name of // *this* file. $wgValidSkinNames['refreshed'] = 'Refreshed'; // Autoload the skin classes, set up i18n, set up CSS & JS (via ResourceLoader) $wgAutoloadClasses['SkinRefreshed'] = __DIR__ . '/Refreshed.skin.php'; $wgAutoloadClasses['RefreshedTemplate'] = __DIR__ . '/Refreshed.skin.php'; $wgMessagesDirs['SkinRefreshed'] = __DIR__ . '/i18n'; $wgResourceModules['skins.refreshed'] = array( 'styles' => array( # Styles custom to the Refreshed skin 'skins/Refreshed/refreshed/main.css' => array( 'media' => 'screen' ), + 'skins/Refreshed/refreshed/wikifont/wikiglyphs.css' => array( 'media' => 'screen' ), 'skins/Refreshed/refreshed/small.css' => array( 'media' => '(max-width: 600px)' ), 'skins/Refreshed/refreshed/medium.css' => array( 'media' => '(min-width: 601px) and (max-width: 1000px)' ), 'skins/Refreshed/refreshed/big.css' => array( 'media' => '(min-width: 1001px)' ), ), 'position' => 'top' ); $wgResourceModules['skins.refreshed.js'] = array( 'scripts' => 'skins/Refreshed/refreshed/refreshed.js', ); $wgHooks['BeforePageDisplay'][] = function( &$out, &$skin ) { // Add the viewport meta tag for users who are using this skin // The skin class check has to be present because hooks are global! if ( get_class( $skin ) == 'SkinRefreshed' ) { $out->addMeta( 'viewport', 'width=device-width' ); } return true; }; $wgRefreshedHeader = array( 'img' => '', 'url' => 'http://meta.brickimedia.org/wiki/Main_Page', 'dropdown' => array() // format: array( 'http://exampleurl.com' => '', ); -); \ No newline at end of file +); diff --git a/Refreshed.skin.php b/Refreshed.skin.php index 88207a7..0f06c6f 100644 --- a/Refreshed.skin.php +++ b/Refreshed.skin.php @@ -1,497 +1,491 @@ getRequest()->getFuzzyBool( 'debug' ) ? '.src' : '.min'; // Add CSS @media support for older browsers (such as Internet Explorer // 8) that do not support it natively // @see https:// github.com/Brickimedia/brickimedia/issues/224 // @todo FIXME: add Respond into the resources directory // (skins/Refreshed/refreshed) and load it from there instead of from GitHub // Remember to use the global variable $wgLocalStylePath, just like how // Vector does! $out->addHeadItem( 'css3mediaquerypolyfill', '' ); $out->addHeadItem( 'viewportforios', Html::element( 'meta', array( 'name' => 'viewport', 'content' => 'width=device-width, initial-scale=1.0' ) ) ); // preventing iOS from zooming out when the sidebar is opened // Add JavaScript via ResourceLoader $out->addModules( 'skins.refreshed.js' ); } function setupSkinUserCss( OutputPage $out ) { global $wgStylePath; parent::setupSkinUserCss( $out ); // Add CSS via ResourceLoader $out->addModuleStyles( array( 'mediawiki.skinning.interface', 'mediawiki.skinning.content.externallinks', 'skins.refreshed' ) ); // Internet Explorer fixes $out->addStyle( $wgStylePath . '/Refreshed/refreshed/ie8.css', 'screen', 'IE 8' ); } } class RefreshedTemplate extends BaseTemplate { public function execute() { global $wgStylePath, $wgRefreshedHeader, $wgMemc; $skin = $this->getSkin(); $user = $skin->getUser(); // Title processing $titleBase = $this->getSkin()->getTitle(); $title = $titleBase->getSubjectPage(); $titleNamespace = $titleBase->getNamespace(); $refreshedImagePath = "$wgStylePath/Refreshed/refreshed/images"; $key = wfMemcKey( 'refreshed', 'header' ); $headerNav = $wgMemc->get( $key ); if ( !$headerNav ) { $headerNav = array(); $skin->addToSidebar( $headerNav, 'refreshed-navigation' ); $wgMemc->set( $key, $headerNav , 60 * 60 * 24 ); // 24 hours } // Output the tag and whatnot $this->html( 'headelement' ); ?>
data['sitenotice'] ) { ?>
html( 'sitenotice' ) ?>
html( 'newtalk' ) ?>

html( 'title' ) ?>

getIndicators(); } ?>
getToolbox(); // if there are actions like "edit," etc. // (not counting generic toolbox tools like "upload file") // in addition to non-page-specific ones like "page" (so a "more..." link is needed) if ( sizeof( $this->data['content_actions'] ) > 1 ) { foreach ( $this->data['content_actions'] as $key => $action ) { if ( !$lastLinkOutsideOfStandardToolboxDropdownHasBeenGenerated ) { // this runs until all the actions outside the dropdown have been generated (generates actions outside dropdown) echo $this->makeLink( $key, $action ); $amountOfToolsGenerated++; if ( sizeof( $this->data['content_actions'] ) == $amountOfToolsGenerated || $key == 'history' || $key == 'addsection' || $key == 'protect' || $key == 'unprotect' ) { // if this is the last action or it is the // history, new section, or protect/unprotect action // (whichever comes first) $lastLinkOutsideOfStandardToolboxDropdownHasBeenGenerated = true; ?>
getMsg( 'moredotdotdot' )->text() ?>
msg( 'tagline' ) ?>
html( 'userlangattributes' ) ?>>html( 'subtitle' ) ?>
html( 'undelete' ) ?>
getPrefixedText() )->escaped(), array( 'id' => 'back-to-subject' ) ); } ?>
data['content_actions'] ); $pageTab = key( $this->data['content_actions'] ); $isEditing = in_array( $this->getSkin()->getRequest()->getText( 'action' ), array( 'edit', 'submit' ) ); // determining how many tools need to be generated $totalSmallToolsToGenerate = 0; $listOfToolsToGenerate = array( - 'ca-talk', - 'ca-viewsource', - 'ca-edit', - 'ca-history', - 'ca-delete', - 'ca-move', - 'ca-protect', - 'ca-unprotect', - 'ca-watch', - 'ca-unwatch' + 'wikiglyph wikiglyph-speech-bubbles' => 'ca-talk', + 'wikiglyph wikiglyph-pencil-lock-full' => 'ca-viewsource', + 'wikiglyph wikiglyph-pencil' => 'ca-edit', + 'wikiglyph wikiglyph-clock' => 'ca-history', + 'wikiglyph wikiglyph-trash' => 'ca-delete', + 'wikiglyph wikiglyph-move' => 'ca-move', + 'wikiglyph wikiglyph-lock' => 'ca-protect', + 'wikiglyph wikiglyph-unlock' => 'ca-unprotect', + 'wikiglyph wikiglyph-star' => 'ca-watch', + 'wikiglyph wikiglyph-unstar' => 'ca-unwatch' ); foreach ( $this->data['content_actions'] as $action ) { if ( in_array( $action['id'], $listOfToolsToGenerate ) ) { // if the icon in question is one of the listed ones $totalSmallToolsToGenerate++; } } if ( MWNamespace::isTalk( $titleNamespace ) ) { // if talk namespace $totalSmallToolsToGenerate--; // remove a tool (the talk page tool) if the user is on a talk page } if ( $totalSmallToolsToGenerate > 0 && !$isEditing ) { // if there's more than zero tools to be generated and the user isn't editing a page ?>
-
+
data['content_actions'] as $action ) { if ( $smallToolboxToolCount > $amountOfSmallToolsToSkipInFront ) { // if we're not supposed to skip this tool (e.g. if we're supposed to skip the first 2 tools and we're at the 3rd tool, then the boolean is true) // @todo Maybe write a custom makeLink()-like function for generating this code? + if ( $totalSmallToolsToGenerate > 3 && $smallToolboxToolCount - $amountOfSmallToolsToSkipInFront == 3 ) { // if there are more than three tools to generate (so a more button is needed) and the third tool is currently being generated + ?> - -
- 2 ) { - ?> - -
html( 'bodytext' ) ?>
html( 'catlinks' ); if ( $this->data['dataAfterContent'] ) { $this->html( 'dataAfterContent' ); } ?>
printTrail(); echo Html::closeElement( 'body' ); echo Html::closeElement( 'html' ); } -} \ No newline at end of file +} diff --git a/refreshed/refreshed.js b/refreshed/refreshed.js index 037ecca..adbc68d 100644 --- a/refreshed/refreshed.js +++ b/refreshed/refreshed.js @@ -1,413 +1,413 @@ /* global $ */ window.Refreshed = { standardToolboxIsDocked: false, standardToolboxInitialOffset: $( '.standard-toolbox' ).offset().top, scrollHeaderHasBeenGenerated: false, usingIOS: false, thresholdForSmallCSS: 601, windowStartedSmall: false, thresholdForBigCSS: 1001, searchDropdownOpen: false, userToolsOpen: false, siteNavOpen: false, windowIsBig: false, windowIsSmall: false, widthOfSpecialSearchBar: 0, widthOfSpecialSearchPowerSearchBar: 0, sidebarOpen: false, flyOutScrollHeader: function() { if ( $( '#content' ).height() > $( window ).height() - $( '#header' ).height() && !Refreshed.standardToolboxIsDocked && ( $( '.static-toolbox' ).offset().top - $( document ).scrollTop() - $( '#header' ).height() < 0 ) ) { // first condition: only move the scroll header if the article // content is bigger than the page (i.e. preventing it from being // triggered when a user "rubber band scrolls" in OS X for example) //$( '.fixed-toolbox' ).animate({'top': $( '#header' ).height()}); $( '.fixed-toolbox' ).addClass( 'dropdown-open' ); Refreshed.standardToolboxIsDocked = true; $( '#firstHeading > .standard-toolbox .standard-toolbox-dropdown' ).fadeOut(); } else if ( Refreshed.standardToolboxIsDocked && $( document ).scrollTop() + $( '#header' ).height() <= Refreshed.standardToolboxInitialOffset ) { Refreshed.standardToolboxIsDocked = false; //$( '.fixed-toolbox' ).animate({'top': -$( '.fixed-toolbox' ).height()}); $( '.fixed-toolbox' ).removeClass( 'dropdown-open' ); $( '.fixed-toolbox .standard-toolbox-dropdown' ).fadeOut(); } }, generateScrollHeader: function() { $( '.static-toolbox' ).clone().removeClass( 'static-toolbox' ).addClass( 'fixed-toolbox' ).insertBefore( '#sidebar-wrapper' ); //$( '.fixed-toolbox' ).css({'top': -$( '.fixed-toolbox' ).height()}); if ( $( '.fixed-toolbox' ).outerWidth() != $( '#bodyContent' ).outerWidth() ) { // if standard-toolboxoverlay hasn't has its width set by CSS calc $( '.fixed-toolbox' ).css({'width': $( '#bodyContent' ).outerWidth() - ( $( '.fixed-toolbox' ).outerWidth() - $( '.fixed-toolbox' ).width() )}); // set .fixed-toolbox's width to the width of #bodyContentminus .fixed-toolbox's padding (and border, which is 0) } Refreshed.scrollHeaderHasBeenGenerated = true; }, resizeScrollHeader: function() { // set .fixed-toolbox's width to the width of #bodyContentminus .fixed-toolbox's padding (and border, which is 0) $( '.fixed-toolbox' ).css({'width': $( '#bodyContent' ).outerWidth() - ( $( '.fixed-toolbox' ).outerWidth() - $( '.fixed-toolbox' ).width() )}); }, resizeSpecialSearchBar: function() { if ( !Refreshed.windowIsBig && !Refreshed.windowIsSmall ) { // if running medium.css // set width of search bar to 100% of #bodyContent- "__ of __ results" text - width of submit button - width - 1em in the search bar Refreshed.widthOfSpecialSearchBar = $( '#bodyContent' ).width() - $( '.results-info' ).outerWidth() - $( '#bodyContent #search input[type="submit"]' ).outerWidth() - parseFloat( $( '#searchText' ).css( 'font-size' ) ); Refreshed.widthOfSpecialSearchPowerSearchBar = $( '#bodyContent' ).width() - $( '.results-info' ).outerWidth() - $( '#bodyContent #powersearch input[type="submit"]' ).outerWidth() - parseFloat( $( '#powerSearchText' ).css( 'font-size' ) ); } else if ( Refreshed.windowIsSmall ) { // if running small.css //set width of search bar to 100% of #bodyContent - width of submit button - width - 1em in the search bar Refreshed.widthOfSpecialSearchBar = $( '#bodyContent' ).width() - $( '#bodyContent #search input[type="submit"]' ).outerWidth() - parseFloat( $( '#searchText' ).css( 'font-size' ) ); Refreshed.widthOfSpecialSearchPowerSearchBar = $( '#bodyContent' ).width() - $( '#bodyContent #powersearch input[type="submit"]' ).outerWidth() - parseFloat( $( '#powerSearchText' ).css( 'font-size' ) ); } $( '#searchText' ).css({'width': Refreshed.widthOfSpecialSearchBar}); $( '#powerSearchText' ).css({'width': Refreshed.widthOfSpecialSearchPowerSearchBar}); }, showHideOverflowingDropdowns: function() { $( '.page-item-has-children' ).each(function( ) { if ( $( this ).offset().top > $( '#header' ).height() + $( '#header' ).offset().top ) { //if the .page-item is beneath the bottom of the header (and so it's cut off by overflow:hidden) $( this ).children( '.children' ).css({'display': 'none'}); $( this ).removeClass( 'header-button-active' ); $( this ).children( '.clickable-region' ).children( '.arrow' ).removeClass( 'rotate' ); } } ); } }; $( document ).ready( function() { if ( navigator.userAgent.toLowerCase().match( /(iPad|iPhone|iPod)/i ) ) { // detect if on an iOS device Refreshed.usingIOS = true; } if ( $( window ).width() < Refreshed.thresholdForSmallCSS ) { Refreshed.windowStartedSmall = true; } // test if window is running big.css if ( $( window ).width() >= Refreshed.thresholdForBigCSS ) { Refreshed.windowIsBig = true; } else { Refreshed.windowIsBig = false; } // test if window is running small.css if ( $( window ).width() <= Refreshed.thresholdForSmallCSS ) { Refreshed.windowIsSmall = true; } else { Refreshed.windowIsSmall = false; } Refreshed.resizeSpecialSearchBar(); if ( !Refreshed.usingIOS && !Refreshed.windowStartedSmall ) { // only perform if not on an iOS device (animations triggered by scroll // cannot be played during scroll on iOS Safari) and if the window was // running small.css when loaded Refreshed.generateScrollHeader(); Refreshed.flyOutScrollHeader(); } $( window ).scroll( function() { Refreshed.flyOutScrollHeader(); } ); $( window ).resize( function() { if ( Refreshed.scrollHeaderHasBeenGenerated && $( '.fixed-toolbox' ).outerWidth() != $( '#bodyContent' ).outerWidth() ) { // only perform if the scroll header has already been generated and // it needs to be resized (not already done by CSS calc) Refreshed.resizeScrollHeader(); } if ( $( window ).width() >= Refreshed.thresholdForBigCSS ) { Refreshed.windowIsBig = true; } else { Refreshed.windowIsBig = false; } if ( $( window ).width() <= Refreshed.thresholdForSmallCSS ) { Refreshed.windowIsSmall = true; } else { Refreshed.windowIsSmall = false; } Refreshed.resizeSpecialSearchBar(); Refreshed.showHideOverflowingDropdowns(); } ); /* tools dropdown attached to firstHeading */ $( '#firstHeading > .standard-toolbox #toolbox-link' ).on( { 'click': function() { if ( !$( '#firstHeading > .standard-toolbox .standard-toolbox-dropdown' ).is( ':visible' ) ) { $( '#firstHeading > .standard-toolbox .standard-toolbox-dropdown' ).fadeIn(); } $( this ).children().toggleClass( 'rotate' ); }, 'hover': function() { $( this ).children().toggleClass( 'no-show' ); } } ); $( document ).mouseup( function ( e ) { if ( $( '#firstHeading > .standard-toolbox .standard-toolbox-dropdown' ).is( ':visible' ) ) { if ( !$( '#firstHeading > .standard-toolbox .standard-toolbox-dropdown' ).is( e.target ) && $( '#firstHeading > .standard-toolbox .standard-toolbox-dropdown' ).has( e.target ).length === 0 ) { // if the target of the click isn't the container and isn't a descendant of the container $( '#firstHeading > .standard-toolbox .standard-toolbox-dropdown' ).fadeOut(); } } } ); /* tools dropdown on the "scroll header" */ $( '.fixed-toolbox #toolbox-link' ).on( { 'click': function() { if ( !$( '.fixed-toolbox .standard-toolbox-dropdown' ).is( ':visible' ) ) { $( '.fixed-toolbox .standard-toolbox-dropdown' ).fadeIn(); } $( this ).children().toggleClass( 'rotate' ); }, 'hover': function() { $( this ).children().toggleClass( 'no-show' ); } } ); $( document ).mouseup( function ( e ) { if ( $( '.fixed-toolbox .standard-toolbox-dropdown' ).is( ':visible' ) ) { if ( !$( '.fixed-toolbox .standard-toolbox-dropdown' ).is( e.target ) && $( '.fixed-toolbox .standard-toolbox-dropdown' ).has( e.target ).length === 0 ) { // if the target of the click isn't the container and isn't a descendant of the container $( '.fixed-toolbox .standard-toolbox-dropdown' ).fadeOut(); } } } ); $.fn.extend( { clickOrTouch: function( handler ) { return this.each( function() { var event = ( 'ontouchend' in document ) ? 'touchend' : 'mouseup'; $( this ).on( event, handler ); } ); } } ); /* search dropdown */ $( '#search-shower' ).click( function() { // Unfortunately, touchend causes the search bar to lose focus on iPhones on iOS 7 and iPads on iOS 8 (haven't tested on Android), but it keeps its focus if you used the standard click event. The other menus, etc. use "touchOrClick" b/c the touchend event executes faster than the standard click on iOS (once again, haven't tested on Android). if ( !Refreshed.searchDropdownOpen ) { if ( Refreshed.usingIOS ) { $( window ).scrollTop( 0 ); // iOS tries to vertically center the search bar, scrolling to the top keeps the header at the top of the viewport } $( '#header .search' ).addClass( 'search-open' ); $( '#sidebar-shower' ).addClass( 'sidebar-shower-hidden' ); $( '#fade-overlay' ).addClass( 'fade-overlay-active fade-overlay-below-header' ); // toggle the fade overlay $( '#searchInput' ).focus(); $( this ).toggleClass( 'header-button-active' ); Refreshed.searchDropdownOpen = true; } else { // this only runs in "medium" mode (the search dropdown only // appears in "medium" and "small" mode, and "small" is covered // by the document.click function below) $( '#header .search' ).removeClass( 'search-open' ); $( '#sidebar-shower' ).removeClass( 'sidebar-shower-hidden' ); $( '#searchInput' ).blur().val( '' ); // deselect the search input and reset its contents (remove anything the user entered) $( '#fade-overlay' ).removeClass( 'fade-overlay-active fade-overlay-below-header' ); // toggle the fade overlay $( '#search-shower' ).removeClass( 'header-button-active' ); Refreshed.searchDropdownOpen = false; // no delay needed because the spamming issue is only present on "small" } } ); $( document ).click( function ( e ) { // if you use clickOrTouch, pressing the .suggestions element will cause the window to close on mobile (maybe the clickOrTouch section is executed before a plain click and thus this is run and .search is hidden before the broswer acknowledges the click event on .suggestions to load the searched-for page?) if ( Refreshed.searchDropdownOpen && $( window ).width() < Refreshed.thresholdForBigCSS ) { // window size must be checked because we only want to hide the search bar if we're not in "big" mode if ( !$( '#header .search' ).is( e.target ) && !$( '#search-shower' ).is( e.target ) && !$( '.search input' ).is( e.target ) ) { // if the target of the click isn't the search container, // search button, or the search box itself (we can't set it to // all descendants of .search because #search-closer needs to // be able to close the search box) $( '#header .search' ).removeClass( 'search-open' ); $( '#sidebar-shower' ).removeClass( 'sidebar-shower-hidden' ); $( '#searchInput' ).blur().val( '' ); // deselect the search input and reset its contents (remove anything the user entered) $( '#fade-overlay' ).removeClass( 'fade-overlay-active fade-overlay-below-header' ); //toggle the fade overlay $( '#search-shower' ).removeClass( 'header-button-active' ); // delay variable change for 375ms until after the animation is // complete so both animations don't run on one press setTimeout( function () { Refreshed.searchDropdownOpen = false; }, 375 ); } } } ); /* user tools dropdown */ $( '#user-info > a' ).clickOrTouch( function() { if ( !$( '#user-info .header-menu' ).is( ':visible' ) ) { $( '#user-info .header-menu' ).fadeIn(); $( this ).addClass( 'header-button-active' ); $( '#user-info .arrow' ).addClass( 'rotate' ); // delay the second clickOrTouch function (which performs fadeOut) // to stop fadeIn and fadeOut on one click (also prevents user from // spamming so it constantly fades in/out) setTimeout( function () { Refreshed.userToolsOpen = true; }, 300 ); } } ); $( document ).clickOrTouch( function ( e ) { if ( $( '#user-info .header-menu' ).is( ':visible' ) ) { if ( Refreshed.userToolsOpen && !$( '#user-info .header-menu' ).is( e.target ) && $( '#user-info .header-menu' ).has( e.target ).length === 0 ) { // if the target of the click isn't the button, the container, or a descendant of the container $( '#user-info > a' ).removeClass( 'header-button-active' ); $( '#user-info .header-menu' ).fadeOut(); $( '#user-info .arrow' ).removeClass( 'rotate' ); Refreshed.userToolsOpen = false; } } } ); /* site navigation dropdown */ $( '#site-info-main a.arrow-link' ).clickOrTouch( function() { if ( !$( '#site-info .header-menu' ).is( ':visible' ) ) { $( '#site-info .header-menu' ).fadeIn(); $( '#site-info-main a.arrow-link' ).addClass( 'header-button-active' ); $( '#site-info .arrow' ).addClass( 'rotate' ); // delay the second clickOrTouch function (which performs fadeOut) // to stop fadeIn and fadeOut on one click (also prevents user from // spamming so it constantly fades in/out) setTimeout( function () { Refreshed.siteNavDropdown = true; }, 300 ); } } ); $( document ).clickOrTouch( function ( e ) { if ( $( '#site-info .header-menu' ).is( ':visible' ) ) { if ( Refreshed.siteNavDropdown && !$( '#site-info .header-menu' ).is( e.target ) && $( '#site-info .header-menu' ).has( e.target ).length === 0 ) { // if the target of the click isn't the container and isn't a descendant of the container $( '#site-info .header-menu' ).fadeOut(); $( '#site-info-main a.arrow-link' ).removeClass( 'header-button-active' ); $( '#site-info .arrow' ).removeClass( 'rotate' ); Refreshed.siteNavDropdown = false; } } } ); /* mobile sidebar */ $( '#sidebar-shower' ).clickOrTouch( function() { //if (!Refreshed.sidebarOpen) { $( '#sidebar-wrapper' ).toggleClass( 'sidebar-open' ); $( '#sidebar-shower' ).toggleClass( 'sidebar-open' ); $( '#fade-overlay' ).toggleClass( 'fade-overlay-active' ); // toggle the fade overlay Refreshed.sidebarOpen = !Refreshed.sidebarOpen; $( this ).toggleClass( 'header-button-active' ); //} } ); $( document ).clickOrTouch( function ( e ) { if ( Refreshed.sidebarOpen && $( '#fade-overlay').is( e.target ) ) { // if the sidebar is out and the target of the click is the fade-overlay $( '#sidebar-wrapper' ).removeClass( 'sidebar-open' ); $( '#sidebar-shower' ).removeClass( 'sidebar-open' ); $( '#fade-overlay' ).removeClass( 'fade-overlay-active' ); // deactivate the fade overlay Refreshed.sidebarOpen = false; $( '#sidebar-shower' ).removeClass( 'header-button-active' ); } } ); - $( '#small-toolbox-wrapper > a' ).clickOrTouch( function() { - $( '#small-toolbox' ).css({'overflow': 'auto'}).animate({'width': '100%'}).addClass( 'scroll-shadow' ); + $( '#small-tool-more' ).clickOrTouch( function() { + $( '.small-toolbox' ).addClass( 'small-toolbox-expanded scroll-shadow' ); $( this ).css({'display': 'none'}); } ); $( '#icon-ca-watch, #icon-ca-unwatch' ).parent().clickOrTouch( function( e ) { // AJAX for watch icons var action, api, $link, title, otherAction; e.preventDefault(); e.stopPropagation(); title = mw.config.get( 'wgRelevantPageName', mw.config.get( 'wgPageName' ) ); mw.loader.load( ['mediawiki.notification'], null, true ); action = mw.util.getParamValue( 'action', this.href ); otherAction = action === 'watch' ? 'unwatch' : 'watch'; $link = $( this ); $( 'div', this ).attr( 'id', 'icon-ca-' + otherAction ); $( this ).attr( 'href', this.href.replace( action, otherAction ) ); api = new mw.Api(); api[action]( title ) .done( function ( watchResponse ) { mw.notify( $.parseHTML( watchResponse.message ), { tag: 'watch-self' } ); $( '#wpWatchthis' ).prop( 'checked', watchResponse.watched !== undefined ); } ); } ); /* user tools dropdown */ $( '.page-item-has-children .clickable-region' ).clickOrTouch( function( e ) { // hide all the other page item dropdowns if they are visible $( '.page-item-has-children .children' ).fadeOut( 200 ); $( '.page-item-has-children' ).removeClass( 'header-button-active' ); $( '.page-item-has-children .arrow' ).removeClass( 'rotate' ); if ( !$( this ).siblings( '.children' ).is( ':visible' ) ) { $( this ).siblings( '.children' ).fadeIn( 200 ); $( this ).parent().addClass( 'header-button-active' ); $( this ).children( '.arrow' ).addClass( 'rotate' ); } } ); $( document ).clickOrTouch( function ( e ) { if ( $( '.page-item-has-children .children' ).is( ':visible' ) ) { if ( $( '.page-item-has-children' ).has( e.target ).length === 0 ) { // if the target of the click isn't the button, the container, or a descendant of the container $( '.page-item-has-children .children' ).fadeOut( 200 ); $( '.page-item-has-children' ).removeClass( 'header-button-active' ); $( '.page-item-has-children .arrow' ).removeClass( 'rotate' ); } } } ); /** * add "header-suggestions" class to first .suggestions element for CSS * targeting (there is usually one .suggestions element, but on Special:Search * there is one for the #header search bar and one for the #bodyContentsearch bar) */ setTimeout( function () { // wait a bit so the .suggestions elements can be added in (if we don't wait we'll be targeting nothing and it won't work)... $( '.suggestions' ).first().addClass( 'header-suggestions' ); // add class to first .suggestions element }, 100 ); } ); /* Fix for Echo in Refreshed */ if ( document.getElementById( 'echo' ) ) { $( '#pt-notifications' ).prependTo( '#echo' ); } if ( $( '.mw-echo-notifications-badge' ).hasClass( 'mw-echo-unread-notifications' ) ) { $( '#pt-notifications-personaltools a' ).addClass( 'pt-notifications-personaltools-unread' ); } diff --git a/refreshed/small.css b/refreshed/small.css index c5621ce..bae3fee 100644 --- a/refreshed/small.css +++ b/refreshed/small.css @@ -1,489 +1,440 @@ /* anything 600px and under - phones */ .fade-overlay-active { opacity: 0.5 !important; z-index: 10001; /* very high value to guarantee no elements on wikis will appear above it (except the sidebar) */ cursor: pointer; } .fade-overlay-below-header { z-index: 10000 !important; /* below header but above page content (used for search) */ cursor: pointer; } #header { height: 2.75em; } #sidebar-wrapper { position: fixed; background: midnightblue; left: -15em; width: 15em; top: 0; z-index: 10002; /* appear above fade-overlay, which has z-index 10001 */ -o-transition: 0.2s ease; -moz-transition: 0.2s ease; -webkit-transition: 0.2s ease; /* -webkit- last so it's used in place of -o- if possible */ transition: 0.2s ease; } .sidebar-open { left: 0; -ms-transform: translateX(15em); -o-transform: translateX(15em); -moz-transform: translateX(15em); -webkit-transform: translateX(15em); /* -webkit- last so it's used in place of -o- if possible */ transform: translateX(15em); } #sidebar { top: 2.75em; font-size: 13pt; } #sidebar a:hover { border: 0; margin-left: 5px; } .header-button { width: 2.75em; height: 2.75em; background-size: 2.75em 2.75em; } #sidebar-shower { display: block; } .sidebar-shower-hidden { right: 0 !important; } #sidebar-logo { position: absolute; top: 0; left: 0; display: block; width: 100%; height: 2.75em; text-align: center; padding: 0.5em 0; } #site-info-main { display: none; } #site-info-main .arrow-link { display: none !important; } #site-info-main:hover, #site-info-main a, #site-info-main a:hover { background: none; } #site-info-mobile { display: inline-block; } #header .search { background: midnightblue; width: 100%; position: absolute; top: 0; left: 0; opacity: 0; padding: 0.25em 0; z-index: 0; } #header .search-open { z-index: 2; /* The notifications badge has a z-index of 1, this puts the search above it */ opacity: 1; } #search-closer { display: block; } #header .search form { margin-right: 3em; margin-left: 0.25em; } #searchInput { /* header search box */ width: 100%; font-size: 18px; float: left; height: 2em; /* (2.75em [height of header] - 0.5em [top + bottom padding of .search]) * (16px [font size of #header and .search] / 18px [font size of .search input]) */ display: none; /* default to hidden (will be shown by adding .search-open class to .search) */ } .search-open #searchInput { display: block; } #search-shower { display: block; position: absolute; top: 0; right: 0; } #searchText, #powerSearchText { /* search and advanced search boxes on Special:Search */ font-size: 18px; } #mw-search-top-table { text-align: center; /* center the search/advanced search boxes and submit button on Special:Search */ } .search-types { width: 100%; /* break search types into 2 columns so the last item doesn't fall onto the next row on very small screens */ } .search-types li { width: 50%; } #mw-searchoptions td { display: block; /* set each namespace under the advanced search preferences on its own line to prevent overflow (but if there's enough room it'll expand so there's two per line) */ } .searchresult { max-width: 100%; /* prevent search results from overflowing */ } #user-info { position: absolute; top: 0; right: 3em; /* search is 2.75em, 0.25em of padding */ margin: 0; width: 2.75em; height: 2.75em; } #user-info .header-button { padding: 0; height: 2.75em; } #user-info .arrow { display: none; } .avatar { top: 7px; /* avatar is 30px, header is 44px */ left: 0.5em; } .avatar-none { display: block; } #user-info > a { padding: 0; height: 2.75em; } #user-info > a span { display: none; } #user-info .header-menu { top: 2.75em; background-color: midnightblue; padding: 0.15em 0 0.15em 0; } #user-info .header-menu a { text-align: left; padding-left: 15px; font-weight: normal; } #user-info .header-menu a:hover { color: #CCC; } #user-info .header-menu a.new:hover { color: #f47d64; } #site-info .header-menu img { font-size: 16px; /* resetting font size for logos in menu so they are the same height as the one outside the menu */ } #content { top: 2.75em; } #header-categories { display: none; } #firstHeading { position: relative; font-size: 0.9em; padding: 0 1em; width: auto; } #firstHeading h1 { overflow-x: auto; white-space: nowrap; border: 0; margin: 0; padding: 0; font-size: 2.25em; } .mw-indicator { display: none !important; /* to unset an individual indicator add the following: #mw-indicator-name { display: inline-block !important; } replacing "name" with the assigned name of the indicator */ } .scroll-shadow { background: -webkit-linear-gradient(90deg, white 20%, rgba(255,255,255,0)), -webkit-linear-gradient(270deg, white 20%, rgba(255,255,255,0)) 100% 0, -webkit-linear-gradient(90deg, #e3e3e3 10%, rgba(255,255,255,0)), -webkit-linear-gradient(270deg, #e3e3e3 10%, rgba(255,255,255,0)) 100% 0; background: linear-gradient(90deg, white 20%, rgba(255,255,255,0)), linear-gradient(270deg, white 20%, rgba(255,255,255,0)) 100% 0, linear-gradient(90deg, #e3e3e3 10%, rgba(255,255,255,0)), linear-gradient(270deg, #e3e3e3 10%, rgba(255,255,255,0)) 100% 0; background: -webkit-linear-gradient(0deg, white 20%, rgba(255,255,255,0)), -webkit-linear-gradient(180deg, white 20%, rgba(255,255,255,0)) 100% 0, -webkit-linear-gradient(0deg, #e3e3e3 10%, rgba(255,255,255,0)), -webkit-linear-gradient(180deg, #e3e3e3 10%, rgba(255,255,255,0)) 100% 0; background: linear-gradient(90deg, white 20%, rgba(255,255,255,0)), linear-gradient(270deg, white 20%, rgba(255,255,255,0)) 100% 0, linear-gradient(90deg, #e3e3e3 10%, rgba(255,255,255,0)), linear-gradient(270deg, #e3e3e3 10%, rgba(255,255,255,0)) 100% 0; background-repeat: no-repeat; background-size: 40px 100%, 40px 100%, 14px 100%, 14px 100%; background-attachment: local, local, scroll, scroll; } .standard-toolbox { display: none; } #main-title-messages { display: none; } #back-to-subject { display: block; } #small-toolbox-wrapper { position: relative; display: block; border-top: 1px solid #eaeaea; border-bottom: 1px solid #eaeaea; margin: 0 0.9em 0.75em 0.9em; /* left/right: 1em (#bodyContent padding-left) * 0.9em (#bodyContent font-size) */ overflow-y: hidden; } -#small-toolbox { +.small-toolbox { position: relative; - width: 6em; - height: 3em; + font-size: 2.75em; + width: 3.75em; /* needs 1em for three icons plus .25em of padding to the right of each icon, so 3.75em */ + height: 1em; + overflow-y: hidden; /* wikiglyphs have a bit too much bottom padding; with 1em height they're centered but you can scroll vertically, this stops the vertical scroll */ white-space: nowrap; overflow: hidden; display: inline-block; + -o-transition: width 0.2s ease; + -moz-transition: width 0.2s ease; + -webkit-transition: width 0.2s ease; /* -webkit- last so it's used in place of -o- if possible */ + transition: width 0.2s ease; } -.small-icon { - width: 3em; - height: 3em; - background-size: 2.5em 2.5em; - background-position: .5em .5em; - background-repeat: no-repeat; - display: inline-block; -} - -.small-icon:hover { - opacity: 0.5; -} - -#icon-ca-talk { - /* @embed */ - background-image: url(images/wikifont/wf-icon-speechbubbles.svg); -} - -#icon-ca-viewsource { - /* @embed */ - background-image: url(images/wikifont/wf-icon-editlock.svg); - opacity: 0.3; -} - -#icon-ca-viewsource:hover { - opacity: 0.2; -} - -#icon-ca-edit { - /* @embed */ - background-image: url(images/wikifont/wf-icon-edit.svg); -} - -#icon-ca-history { - /* @embed */ - background-image: url(images/wikifont/wf-icon-clock.svg); -} - -#icon-ca-delete { - /* @embed */ - background-image: url(images/wikifont/wf-icon-trash.svg); -} - -#icon-ca-move { - /* @embed */ - background-image: url(images/wikifont/fa-edited-icon-move.svg); -} - -#icon-ca-protect { - /* @embed */ - background-image: url(images/wikifont/wf-icon-lock.svg); -} - -#icon-ca-unprotect { - /* @embed */ - background-image: url(images/wikifont/wf-icon-unlock.svg); -} - -#icon-ca-watch { - /* @embed */ - background-image: url(images/wikifont/wf-icon-star.svg); +.small-toolbox-expanded { + width: 100%; + overflow-x: auto; } -#icon-ca-unwatch { - /* @embed */ - background-image: url(images/wikifont/wf-icon-unstar.svg); +a.small-tool { /* inclusion of the "a" is necessary to override the standard a element font color without using !important */ + font-size: 1em; + width: 1em; + height: 1em; + color: #000; + display: inline-block; + padding-right: .25em; } -#icon-more { - /* @embed */ - background-image: url(images/wikifont/wf-icon-ellipsis.svg); +.small-tool:hover { + opacity: 0.5; } /* CONTENT AREA ********************************************/ .nosmall, .articleFeedbackv5 { display: none !important; } /* Hide ads on mobile until mobile ads are implemented */ #advert { display: none; } /* Suggestions box under search */ .header-suggestions { top: 2.75em !important; left: 0 !important; width: 100% !important; font-size: 16px !important; z-index: 10001 !important; /* place above #fade-overlay, which has z-index of 10000 because it has the .fade-overlay-below-header class */ } .header-suggestions div { font-size: 16pt; } .header-suggestions .suggestions-result { padding: 0.5em 0.25em !important; border-bottom: 1px solid #ddd; } .header-suggestions .suggestions-special { padding: 0.5em 0.25em !important; margin-top: 0 !important; border: 0 !important; border-bottom: 1px solid #ddd !important; } .header-suggestions .suggestions-results { border: 0 !important; } /* Extension:Echo fixes */ #pt-mytalk a.mw-echo-alert { /* "you have new messages" alert in the personal tools dropdown */ margin: 0.1em; } #pt-notifications-personaltools { /* "Notifications" item in the personal tools dropdown */ display: list-item; } .pt-notifications-personaltools-unread { background-color: #cc0000; color: #fff; border-radius: 2px; /* matching the notification badge itself and the "you have new messages" notice, which both have border-radius */ margin: 0.1em; } .pt-notifications-personaltools-unread:hover { background-color: #bf0000 !important; } #pt-notifications { position: absolute; margin: 0; top: 0; /* the container height is greater than that of the notification button itself so this still leaves some space above the button */ right: 2.9em; /* 2.75em for the search button, 0.25em of padding within user button */ max-width: 2.25em; /* 2.75em (width of user button) - 0.25em of padding on each side */ z-index: 1; /* above user button */ padding: 0; width: auto; pointer-events: none; /* prevent click event (stop notifications dropdown from appearing on click) */ } .mw-echo-notifications-badge { font-size: 0.5em; min-width: 3.5px; /* min-width of 7px * 0.5em (stops badge from looking too wide when it contains a single-digit number) */ max-width: 2.25em; /* (2.75em (width of user button) - 0.25em of padding on each side) * 2 because the font size is 0.5em */ overflow: hidden; display: none; /* hide if there are no noticiations */ } .mw-echo-unread-notifications { display: inline; } .mw-echo-overlay { display: none; /* if pointer-events isn't supported (so #mw-echo-overlay is generated when the notifications badge is clicked), hide #mw-echo-overlay so it's not visible */ } /* Image thumbnails */ .thumb { width: 100% !important; margin: 0 !important; } div.thumbinner { /* need to specify div so it can overwrite the CSS in commonContent.css */ width: auto !important; padding: 0.75em 0 !important; margin-bottom: 0.5em; } .thumbinner img { width: 50%; height: auto; border: 0 !important; } .thumbcaption { text-align: center !important; margin-bottom: -.75em !important; } .magnify { display: none; }