Responsive support, JS edition
Dropdown menus and js interactiveness for people who like to pretend we live in a modern era or something. Does not actually support newfangled tapping and swiping stuff. Does not properly support echo. (will follow up) Change-Id: I27d50c320b1526b9d158016a0e8022567f78ccc1
This commit is contained in:
parent
70d426d4fd
commit
0e2ee04c87
13 changed files with 369 additions and 70 deletions
|
@ -50,6 +50,9 @@ class SkinMonoBook extends SkinTemplate {
|
|||
'mediawiki.skinning.content.externallinks',
|
||||
'skins.monobook.styles'
|
||||
] );
|
||||
$out->addModules( [
|
||||
'skins.monobook.mobile'
|
||||
] );
|
||||
|
||||
// TODO: Migrate all of these (get RL support for conditional IE)
|
||||
// Force desktop styles in IE 8-; no support for @media widths
|
||||
|
|
BIN
resources/images/icon-close.gif
Normal file
BIN
resources/images/icon-close.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 226 B |
21
resources/images/icon-close.svg
Normal file
21
resources/images/icon-close.svg
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 4.233 4.233">
|
||||
<defs>
|
||||
<radialGradient id="b" cx="2.117" cy="1.852" r="1.521" fx="2.117" fy="1.852" gradientTransform="matrix(1.04348 0 0 1 -.092 0)" gradientUnits="userSpaceOnUse" xlink:href="#a"/>
|
||||
<linearGradient id="a">
|
||||
<stop offset="0" stop-color="#f60f0f"/>
|
||||
<stop offset=".696" stop-color="#f97e54"/>
|
||||
<stop offset="1" stop-color="#f10000"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path fill="url(#b)" fill-rule="evenodd" d="M.794 1.323l.264-.53.53-.264c.264-.264.793-.264 1.058 0l.529.265.265.529c.264.264.264.794 0 1.058l-.265.53-.53.264c-.264.265-.793.265-1.058 0l-.529-.265-.264-.529c-.265-.264-.265-.794 0-1.058z"/>
|
||||
<path fill="#fff" d="M1.588 1.323h.265v.265h-.265z"/>
|
||||
<path fill="#fff" d="M1.852 1.587v.53h.529v-.53h-.264zM2.381 2.117h.265v.265h-.265z"/>
|
||||
<path fill="#fff" d="M2.381 1.323h.265v.265h-.265zM1.588 2.117h.265v.265h-.265z"/>
|
||||
<path fill="#faa" d="M1.587 1.058v.265h.265v-.265zm0 .265h-.264v.264h.264zm.794-.265v.265h.265v-.265zm.265.265v.264h.264v-.264zm-1.323.794v.264h.264v-.264zm.264.264v.265h.265V2.38zm1.059-.264v.264h.264v-.264zm0 .264H2.38v.265h.265z"/>
|
||||
<path fill="#ffb5b5" d="M1.852 1.323v.264h.53v-.264zm.53.264v.53h.264v-.53zm0 .53h-.53v.264h.53zm-.53 0v-.53h-.265v.53z"/>
|
||||
<path fill="#ffd5d5" d="M1.323 1.058v.265h.264v-.265zm1.323 0v.265h.264v-.265zM1.323 2.381v.265h.264V2.38zm1.323 0v.265h.264V2.38z"/>
|
||||
<path fill="#8b8b8b" d="M1.587.265v.264h.794V.265zm0 .264h-.529v.265h.53zm-.529.265H.794v.529h.264zm-.264.529H.529V2.38h.265zm0 1.058v.53h.264v-.53zm.264.53v.264h.53V2.91zm.53.264v.265h.264v-.265z"/>
|
||||
<path fill="#4e4e4e" d="M2.381.265v.264h.265V.265zm.265.264v.265h.529V.529zm.529.265v.529h.265v-.53zm.265.529V2.38h.264V1.323zm0 1.058h-.265v.53h.265zm-.265.53h-.53v.264h.53zm-.53.264h-.793v.265h.794z"/>
|
||||
<path fill="#fff" fill-rule="evenodd" d="M1.587 1.058l-.264.265.53.53-.53.528.264.265.53-.53.529.53.264-.265-.529-.529.53-.53-.265-.264-.53.53z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.1 KiB |
BIN
resources/images/icon-edit.gif
Normal file
BIN
resources/images/icon-edit.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 202 B |
41
resources/images/icon-edit.svg
Normal file
41
resources/images/icon-edit.svg
Normal file
|
@ -0,0 +1,41 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 4.233 4.233">
|
||||
<defs>
|
||||
<linearGradient id="b">
|
||||
<stop offset="0" stop-color="#fae7d1"/>
|
||||
<stop offset="1" stop-color="#efaf67"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="a">
|
||||
<stop offset="0" stop-color="#f9dccc"/>
|
||||
<stop offset="1" stop-color="#dd9873"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="c">
|
||||
<stop offset="0" stop-color="#faeca8"/>
|
||||
<stop offset=".213" stop-color="#fcf4b3"/>
|
||||
<stop offset=".299" stop-color="#f4d644"/>
|
||||
<stop offset=".484" stop-color="#faee8e"/>
|
||||
<stop offset="1" stop-color="#e4ba2f"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="f" x1="2.873" x2="3.241" y1="1.013" y2="1.373" gradientUnits="userSpaceOnUse" xlink:href="#a"/>
|
||||
<linearGradient id="e" x1="1.147" x2="1.323" y1="2.716" y2="3.175" gradientUnits="userSpaceOnUse" xlink:href="#b"/>
|
||||
<linearGradient id="d" x1="1.587" x2="2.381" y1="1.587" y2="2.381" gradientUnits="userSpaceOnUse" xlink:href="#c"/>
|
||||
</defs>
|
||||
<path fill="url(#d)" fill-rule="evenodd" d="M1.058 2.117L2.25.926l.794.794-1.19 1.19z"/>
|
||||
<path fill="url(#e)" fill-rule="evenodd" d="M1.19 2.249l-.396.132-.133.926.927-.132.132-.397z"/>
|
||||
<path fill="#4e4e4e" d="M.794 3.175v.265h.794v-.265zm.794-.265h.265v.265h-.265z"/>
|
||||
<path fill="#4e4e4e" d="M1.852 2.646h.265v.265h-.265zm.265-.265h.265v.265h-.265z"/>
|
||||
<path fill="#4e4e4e" d="M2.381 2.117h.265v.265h-.265zm.265-.265h.265v.265h-.265z"/>
|
||||
<path fill="url(#f)" fill-rule="evenodd" d="M2.249.926l.397-.397.397-.132.529.529-.132.397-.397.397z"/>
|
||||
<path fill="#4e4e4e" d="M2.91 1.587h.265v.265H2.91z"/>
|
||||
<path fill="#4e4e4e" d="M3.175 1.323h.265v.265h-.265zm.265-.265h.265v.265H3.44z"/>
|
||||
<path fill="#8b8b8b" d="M2.646.265v.264h.529V.265zm.529.264v.265h.265V.529zm.265.265v.264h.264V.794zM2.646.529H2.38v.265h.265zM2.38.794h-.264v.264h.264zm-.264.264h-.265v.265h.265zm-.265.265h-.264v.264h.264zm-.264.264h-.265v.265h.265zm-.265.265h-.265v.265h.265zm-.265.265H.794v.264h.264zm-.264.264H.529V3.44h.265z"/>
|
||||
<path fill="#a3a3a3" d="M2.91 3.175v.265H1.852v-.265z"/>
|
||||
<path fill="#e6e6e6" d="M2.91 3.175v.265h.53v-.265z"/>
|
||||
<path fill="#584013" d="M.794 2.91v.265h.264V2.91z"/>
|
||||
<path fill="#e89840" d="M1.058 2.117v.264h.265v-.264zm.265.264v.265h.265V2.38z"/>
|
||||
<path fill="#c26715" d="M1.588 2.646v.264h.264v-.264z"/>
|
||||
<path fill="#f4c2a7" d="M2.91.53v.264h.265V.529zm-.529.528v.265h.265v-.265z"/>
|
||||
<path fill="#dd9873" d="M3.175.794v.264h.265V.794zm-.53.529v.264h.265v-.264z"/>
|
||||
<path fill="#d49c5d" d="M1.058 2.91v.265h.265V2.91z"/>
|
||||
<path fill="#f6d4ad" d="M.794 2.646v.264h.264v-.264z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.8 KiB |
92
resources/mobile.js
Normal file
92
resources/mobile.js
Normal file
|
@ -0,0 +1,92 @@
|
|||
( function ( mw, $ ) {
|
||||
$( function () {
|
||||
var mobileCutoffWidth = 850,
|
||||
// Track if DOM has been set up for mobile fanciness yet
|
||||
monobookMobileElements = false,
|
||||
// Toggles and targets for popouts
|
||||
toggles = {
|
||||
'#sidebar-toggle': '#sidebar-mobilejs',
|
||||
'#p-personal-toggle': '#p-personal',
|
||||
'#ca-more a': '#p-cactions',
|
||||
'#ca-languages a': '#p-lang',
|
||||
'#ca-tools a': '#p-tb'
|
||||
};
|
||||
|
||||
// Close menus
|
||||
function closeMenus() {
|
||||
$( '.mobile-menu-active' ).removeClass( 'mobile-menu-active' );
|
||||
$( '.menus-cover' ).removeClass( 'visible' );
|
||||
}
|
||||
|
||||
// Set up DOM for mobile fanciness
|
||||
// We don't automatically do this because MonoBook; most users will be on desktop
|
||||
function setupMonoBookMobile() {
|
||||
if ( !monobookMobileElements && $( window ).width() <= mobileCutoffWidth ) {
|
||||
// Duplicate nav
|
||||
$( '#column-one' ).append(
|
||||
$( '#sidebar' ).clone().find( '*' ).addBack().each( function () {
|
||||
if ( this.id ) {
|
||||
this.id = this.id + '-mobilejs';
|
||||
}
|
||||
} ).end().end()
|
||||
);
|
||||
// Thing to fade out the content while menus are active
|
||||
$( '#column-one' ).append( $( '<div id="menus-cover-background" class="menus-cover">' ) );
|
||||
$( '#column-one' ).append( $( '<div id="menus-cover" class="menus-cover">' ) );
|
||||
|
||||
// Add extra cactions tabs - edit, editsource, contributions
|
||||
// Wrap in function to keep jenkins from whining
|
||||
$( function () {
|
||||
var newTabs = [
|
||||
'ca-edit',
|
||||
// 'ca-ve-edit', // TODO when VE is more usable to begin with here
|
||||
// 'ca-watch', 'ca-unwatch', // Maybe?
|
||||
't-contributions'
|
||||
];
|
||||
$.each( newTabs, function ( i, item ) {
|
||||
var a = $( '#' + item + ' a' );
|
||||
|
||||
if ( a.length ) {
|
||||
mw.util.addPortletLink(
|
||||
'p-cactions-mobile',
|
||||
a.attr( 'href' ),
|
||||
a.text(),
|
||||
a.parent().attr( 'id' ) + '-mobile',
|
||||
a.attr( 'tooltip' ),
|
||||
a.attr( 'accesskey' ),
|
||||
'#ca-more'
|
||||
);
|
||||
}
|
||||
} );
|
||||
} );
|
||||
|
||||
// Add close buttons
|
||||
$.each( toggles, function ( toggle, target ) {
|
||||
$( target ).append( $( '<div class="mobile-close-button">' ) );
|
||||
} );
|
||||
|
||||
// Open menus
|
||||
$.each( toggles, function ( toggle, target ) {
|
||||
$( toggle ).on( 'click', function () {
|
||||
if ( $( window ).width() <= mobileCutoffWidth ) {
|
||||
$( target ).addClass( 'mobile-menu-active' );
|
||||
$( '.menus-cover' ).addClass( 'visible' );
|
||||
}
|
||||
// Don't still link to # targets
|
||||
return false;
|
||||
} );
|
||||
} );
|
||||
|
||||
$( '.mobile-close-button, .menus-cover' ).click( closeMenus );
|
||||
// TODO: tap events on same (if not already included in 'click') - also close
|
||||
// TODO: appropriate swipe event(s) - also close
|
||||
|
||||
monobookMobileElements = true;
|
||||
}
|
||||
}
|
||||
|
||||
$( window ).resize( setupMonoBookMobile );
|
||||
setupMonoBookMobile();
|
||||
} );
|
||||
|
||||
}( mediaWiki, jQuery ) );
|
107
resources/mobile.js.less
Normal file
107
resources/mobile.js.less
Normal file
|
@ -0,0 +1,107 @@
|
|||
@import 'variables.less';
|
||||
|
||||
// remove duplicates we're not using here; this is cleaner and/or easier than in js
|
||||
#sidebar .generated-sidebar,
|
||||
*[ id^='ca-nstab-' ],
|
||||
#ca-talk,
|
||||
#ca-edit,
|
||||
#t-contributions,
|
||||
#p-search-mobilejs,
|
||||
#p-tb-mobilejs,
|
||||
#p-lang-mobilejs {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// popouts
|
||||
#p-cactions,
|
||||
#p-personal,
|
||||
#p-tb,
|
||||
#p-lang,
|
||||
#sidebar-mobilejs {
|
||||
display: none;
|
||||
|
||||
&.mobile-menu-active {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.mobile-menu-active {
|
||||
position: absolute;
|
||||
z-index: 10000;
|
||||
top: 2em;
|
||||
left: 0;
|
||||
background: @content-background;
|
||||
border: solid 1px @orange-border;
|
||||
border-left: 0;
|
||||
padding: 2em 2em 0 1.5em;
|
||||
font-size: 125%;
|
||||
|
||||
ul {
|
||||
padding-top: 1em;
|
||||
}
|
||||
|
||||
li {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
a {
|
||||
display: block;
|
||||
padding: 0.65em 0;
|
||||
}
|
||||
|
||||
h3:first-child {
|
||||
margin-right: 2em;
|
||||
}
|
||||
|
||||
.pBody {
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
.mobile-close-button {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
.background-image-svg( 'images/icon-close.svg', 'images/icon-close.gif' );
|
||||
background-position: 0 0;
|
||||
background-repeat: no-repeat;
|
||||
position: absolute;
|
||||
top: 1em;
|
||||
right: 0.75em;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.menus-cover {
|
||||
display: none;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 9999;
|
||||
|
||||
&.visible {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
#menus-cover {
|
||||
position: fixed;
|
||||
opacity: 0.45;
|
||||
background-color: @content-background;
|
||||
}
|
||||
#menus-cover-background {
|
||||
position: absolute;
|
||||
background-color: @background;
|
||||
.background-image-svg( 'images/headbg.svg', 'images/headbg.jpg' );
|
||||
background-position: 0 0;
|
||||
background-repeat: no-repeat;
|
||||
opacity: 0.55;
|
||||
}
|
||||
|
||||
#p-cactions-mobile li {
|
||||
&#ca-edit-mobile a {
|
||||
.background-image-svg( 'images/icon-edit.svg', 'images/icon-edit.gif' );
|
||||
}
|
||||
|
||||
&#t-contributions-mobile a {
|
||||
.background-image-svg( 'images/icon-user.svg', 'images/icon-user.gif' );
|
||||
}
|
||||
}
|
|
@ -162,9 +162,7 @@ table.rimage {
|
|||
background: transparent;
|
||||
display: inline;
|
||||
height: 1em;
|
||||
text-transform: lowercase;
|
||||
font-size: 91%;
|
||||
font-weight: normal;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
|
@ -215,23 +213,11 @@ table.rimage {
|
|||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Don't lowercase username */
|
||||
li#pt-userpage {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
/* "Not logged in" text in gray */
|
||||
li#pt-anonuserpage {
|
||||
color: @text-grey;
|
||||
}
|
||||
|
||||
/* Override text-transform on languages where capitalization is significant */
|
||||
.capitalize-all-nouns .portlet h3,
|
||||
.capitalize-all-nouns #p-personal ul,
|
||||
.capitalize-all-nouns #p-cactions ul li a {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
/*
|
||||
** footer
|
||||
*/
|
||||
|
@ -382,11 +368,6 @@ div.mw-lag-warn-high {
|
|||
}
|
||||
}
|
||||
|
||||
/* Sometimes people don't want personal tools to be lowercase! */
|
||||
.no-text-transform {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
/* Tooltips are outside of the normal body code, so this helps make the size of the text sensible */
|
||||
.tipsy {
|
||||
font-size: 127%;
|
||||
|
|
|
@ -46,6 +46,8 @@ div#column-one {
|
|||
|
||||
.portlet h3 {
|
||||
padding: 0 1em 0 0.5em;
|
||||
text-transform: lowercase;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.pBody {
|
||||
|
@ -54,6 +56,23 @@ div#column-one {
|
|||
padding: 0 0.8em 0.3em 0.5em;
|
||||
}
|
||||
|
||||
/* Don't lowercase username */
|
||||
li#pt-userpage {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
/* Override text-transform on languages where capitalization is significant */
|
||||
.capitalize-all-nouns .portlet h3,
|
||||
.capitalize-all-nouns #p-personal ul,
|
||||
.capitalize-all-nouns #p-cactions ul li a {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
/* Sometimes people don't want personal tools to be lowercase! */
|
||||
.no-text-transform {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
/*
|
||||
** Logo properties
|
||||
*/
|
||||
|
@ -308,7 +327,10 @@ li#ca-print {
|
|||
** mobile toggles; not used here
|
||||
*/
|
||||
#p-cactions-mobile,
|
||||
.menu-toggle {
|
||||
#sidebar-mobilejs,
|
||||
.mobile-close-button,
|
||||
.menu-toggle,
|
||||
.menus-cover {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,19 +16,8 @@ div#column-content {
|
|||
/*
|
||||
** Navigation
|
||||
*/
|
||||
@top-position: 5px;
|
||||
@block-size: 35px;
|
||||
|
||||
.menu-toggle {
|
||||
display: block;
|
||||
width: @block-size;
|
||||
height: @block-size;
|
||||
background: @content-background;
|
||||
border: solid 1px @orange-border;
|
||||
box-sizing: border-box;
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
z-index: 4;
|
||||
.menu-button();
|
||||
}
|
||||
|
||||
#sidebar-toggle {
|
||||
|
@ -110,11 +99,12 @@ div#column-content {
|
|||
}
|
||||
|
||||
/*
|
||||
** site nav
|
||||
** site nav, nojs layout
|
||||
*/
|
||||
.client-nojs {
|
||||
#p-cactions,
|
||||
#p-personal,
|
||||
.generated-sidebar,
|
||||
#sidebar .generated-sidebar,
|
||||
#p-tb,
|
||||
#p-lang {
|
||||
margin: 1em;
|
||||
|
@ -155,6 +145,11 @@ div#column-content {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -252,8 +247,8 @@ div#column-content {
|
|||
|
||||
#f-poweredbyico,
|
||||
#f-copyrightico {
|
||||
display: inline;
|
||||
margin: 0 0.5em;
|
||||
display: inline-block;
|
||||
margin: 0 0.5em 1em;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
6
resources/skinStyles/ext.uls.interface.less
Normal file
6
resources/skinStyles/ext.uls.interface.less
Normal file
|
@ -0,0 +1,6 @@
|
|||
#pt-uls a.uls-trigger {
|
||||
background-size: 16px;
|
||||
}
|
||||
div.uls-menu {
|
||||
margin-top: -2.5em;
|
||||
}
|
|
@ -14,6 +14,22 @@
|
|||
@link-visited: #5a3696;
|
||||
@link-new: #c20;
|
||||
|
||||
// mobile objects
|
||||
@top-position: 5px;
|
||||
@block-size: 35px;
|
||||
|
||||
.menu-button() {
|
||||
display: block;
|
||||
width: @block-size;
|
||||
height: @block-size;
|
||||
background: @content-background;
|
||||
border: solid 1px @orange-border;
|
||||
box-sizing: border-box;
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
// To hide objects, but keep them accessible for screen-readers
|
||||
.hidden() {
|
||||
position: absolute;
|
||||
|
|
17
skin.json
17
skin.json
|
@ -38,6 +38,20 @@
|
|||
"media": "screen and (max-width: 850px)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"skins.monobook.mobile": {
|
||||
"targets": [ "desktop", "mobile" ],
|
||||
"scripts": [
|
||||
"resources/mobile.js"
|
||||
],
|
||||
"styles": {
|
||||
"resources/mobile.js.less": {
|
||||
"media": "screen and (max-width: 850px)"
|
||||
}
|
||||
},
|
||||
"dependencies": [
|
||||
"mediawiki.util"
|
||||
]
|
||||
}
|
||||
},
|
||||
"ResourceFileModulePaths": {
|
||||
|
@ -49,7 +63,8 @@
|
|||
"+mediawiki.action.view.redirectPage": "resources/skinStyles/mediawiki.action.view.redirectPage.css",
|
||||
"+mediawiki.special.preferences.styles": "resources/skinStyles/mediawiki.special.preferences.styles.less",
|
||||
"+mediawiki.notification": "resources/skinStyles/mediawiki.notification.less",
|
||||
"+oojs-ui-core.styles": "resources/skinStyles/ooui.less"
|
||||
"+oojs-ui-core.styles": "resources/skinStyles/ooui.less",
|
||||
"+ext.uls.interface": "resources/skinStyles/ext.uls.interface.less"
|
||||
}
|
||||
},
|
||||
"AutoloadClasses": {
|
||||
|
|
Loading…
Reference in a new issue