User:Yair rand/SWSelectBox.js
Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
- Opera: Press Ctrl-F5.
// SignWriting form element replacements
// Note: This script is only meant to be used in situations where the writing-mode is properly set to vertical.
mw.loader.using(["jquery.ui","mediawiki.ui.button"], function(){ $( document ).ready( function( $ ) {
//$("select").replaceWith("<select><option>M538x518S15a21515x483S15a07463x482S15a01466x483S2a20c493x490</option><option>M521x543S19220500x474S1f720495x498S11920494x517S2a20c479x457</option><option>M511x538S1ce20489x463S14a20490x497S14720491x516</option><option>M515x560S18d20495x440S1f720495x469S11a20500x487S16d20498x521S11502485x545</option><option>M518x566S1f720492x435S14051483x451S11a20497x478S19220497x512S1dc20488x536</option><option>M514x534S18d20488x467S1f720488x497S19a20486x514</option><option>M521x559S19220500x458S2a20c479x441S11520500x480S11920494x513S14a20500x544</option><option>M521x563S19220500x455S2a20c479x438S11520500x477S1dc20491x511S19a20493x543</option><option>M515x534S1f720495x466S11520500x484S1f040486x519</option><option>M516x540S20320498x461S14a20498x480S14051485x495S1fb20498x521</option><option>M509x532S17620493x469S16d20492x489S1fb20494x513</option><option>M511x540S11920490x461S17620495x491S10e20496x510</option><option>M509x537S10120493x464S14a20494x498S16d20492x517</option></select>");
mw.util.addCSS(".swSelect{ -webkit-writing-mode: vertical-lr; writing-mode: tb-lr; -ms-writing-mode: tb-lr; cursor: default; outline: none; display: inline-block; position: relative; vertical-align: middle; white-space: nowrap; color: #000000; }.swSelectSelected{border:#AAA 1px solid; }.swSelectList{border:#AAA 1px solid; max-width: 600px; overflow-x: scroll !important; overflow-y: hidden; position: absolute; z-index: 1; background-color: #FFF; }.swSelectList>div:hover{background-color: #EEEEEE; }.swSelectList>div:active {background-color: #E3E3E3; }.swSelect div.swSelectedOpt{background-color: #D8DDFF; background-color: Highlight; color: HighlightText; }.swSelect .signwritingtext{cursor: default; border-left-width: 0 !important; }body div.swSelectArrow{float: right; margin: 0; margin-top: -2px; background-color: #EEE; border: 1px solid #AAA; }.swSelectArrow>div{background-image: url(//upload.wikimedia.org/wikipedia/commons/4/41/MediaWiki_Vector_skin_right_arrow.png); background-repeat: no-repeat; background-position: 50% 50%; height: 100%; width: 100%; }.swSelectArrow>div>div{ position: relative; width: 100%; height: 0; cursor: default; }.ui-button .signwritingtext,.mw-ui-button .signwritingtext{cursor: inherit; }.mw-ui-button{border-radius:0 !important;}"); // todo: line breaks, merge with other relevant CSS.
var scrollBarHeight = (function(){
var testDiv = $("<div>").css("display", "inline-block").appendTo("#content"),
height = -testDiv.height() + testDiv.css("overflow-x", "scroll").height();
if( height === 0 ) {
height = testDiv.height( 100 )[0].clientHeight - testDiv.css("overflow-x", "visible")[ 0 ].offsetHeight; // measure the scroll bar. can't think of a better way to do this...
}
testDiv.remove();
return height;
})();
$( "select" ).each( function() { // every select needs doing, even if without any SW, so that writing-mode will work
var $select = $( this ).hide(), $fS, $list, $selected, selectedIndex = $select.prop('selectedIndex'), $optSelected, $arrow, width = 0;
$select.after( $fS = $( "<div>" ).attr( "tabindex", 0 ).addClass( "swSelect" ).append( $arrow = $("<div>").addClass( "swSelectArrow ui-button").height( Math.abs( scrollBarHeight ) - 1 ).append( $("<div>").append( $("<div>") ) ) ).append( $selected = $( "<div>" ).addClass("swSelectSelected") ).append( $list = $( "<div>" ).addClass( "swSelectList" ) ) )
$select.find( "option" ).each( function( i ) {
var $option = $( this ), optiontext = $option.text(), $opt = $( "<div>" ).text( optiontext );
$list.append( $opt.on("click", function( e, fake ){
$opt.clone().appendTo( $selected.empty() ).css("color", "#000000");
$select.val( $option.val() ); // update the value of the original select box
$optSelected && $optSelected.removeClass( "swSelectedOpt" );
$optSelected = $opt.addClass( "swSelectedOpt" );
// $arrow.width( $selected.width() );
if( fake ) { // user didn't actually click the box
e.preventDefault();
return false;
}
} ));
signwriting_styled( $opt[ 0 ] ); // activate signwriting
if( $opt.width() > width ) { width = $opt.width(); }
if( i == selectedIndex ){ // originally-selected option
$opt.trigger( "click", true );
}
});
var sH = $list.height();
$selected
.height( sH = sH - ( scrollBarHeight < 0 && scrollBarHeight ) ) // don't shrink as soon as the menu collapses
.width( width ); // set to the width of the largest item, don't bob in and out when switching
$list.hide(); //.css( "overflow-x", "auto" ); // absolute-positioned elements don't handle overflow well
if( scrollBarHeight < 0 ) { // Safari scrollbars shrink the content instead of expanding the box
$list.height( sH );
}
sH -= Math.abs( scrollBarHeight ) - 1;
$arrow.width( width ).find(">div>div").css({ paddingTop: sH, top: -sH }); // extend the range of :hover-causing elements
var w = false, hidden = true, mousePos = false;
$fS.on( "focus blur keydown mouseup", function( e, fake ) {
function updateScroll() {
// $optSelected[ 0 ].scrollIntoView( false ); // doesn't work well in IE
var l = $list[ 0 ], o = $optSelected[ 0 ], a = o.offsetLeft - l.scrollLeft, b = 0;
if( a < 0 || a > ( b = 600 - o.offsetWidth ) ) {
l.scrollLeft += a - b;
}
}
// console.log( e.which );
var t = e.type, key = e.which;
if( t === "mouseup" && ( mousePos === ( mousePos = false ) || e.target === $list[ 0 ] ) ) {
return;
}
// console.log( t, "| hidden = "+hidden, "| w = "+w,"| fake = "+fake, "| mousePos = "+mousePos );
// console.log( e.target );
if( t === "blur" && $( document.activeElement ).closest( ".swSelectList" )[ 0 ] === $list[ 0 ] ) { // for IE
// console.log("wierd blur");
$fS.trigger( "focus", 2 ); // refocus it, but don't let the event handler do anything.
return;
}
if( fake === 2 ){ return; }
if( t === "keydown" && key !== 13 ) {
if( key === 37 || key === 39 || key === 36 || key === 35 ) { // left, right, home, end
$optSelected[ ( { '39' : 'next', '37' : 'prev', '35' : 'nextAll', '36' : 'prevAll' } )[ key ] ]().last().trigger( "click", true );
updateScroll();
e.preventDefault();
} // other non-enter keys do nothing, so far.
} else if(
//!( e.target === $list[ 0 ] ) &&
!( ( t === "blur" || t === "keydown" ) && hidden === true ) && // blur and enter key only toggle to hide
!( t === "focus" && hidden === false ) // focus only toggles to show
) {
if( !w || t === "blur" || ( t === "focus" && fake != true ) ) { // only blur/realfocus get to interrupt an animation
w && $list.stop();
$list.animate({
"width":"toggle","marginLeft":"toggle","marginRight":"toggle","paddingLeft":"toggle","paddingRight":"toggle"
}, 150, function(){ w = false; });
hidden = !hidden;
updateScroll();
}
w = true;
}
}).on( "mousedown", function( e ) {
// console.log("mousedown");
mousePos = hidden === false;
$fS.trigger( "focus", true );
e.preventDefault();
return false;
});
// TODO: relay events from the original select element to the new one, to deal with labels and such.
// probably something like this:
// $select.on( "focus blur keydown mouseup mousedown", function( e ) { $fS.trigger( e ) } );
// also, the original select needs to be counted as existing by the browsers...
// need to do thorough cross-browser testing
});
// Submit buttons
$("input[type='submit']:not(.searchButton)")
//.val("M546x525S2ff00482x483S16d10492x505S2e502519x502")
.each(function()
{
var $t = $( this ).hide(), $s = $( "<div>" ).text( $t.val() || "Submit" ).attr( {"title" : $t.attr( "title" ), "tabindex" : $t.attr( "tabindex" ) || "0" } );
$t.after(
$s.attr( "class", $t.hasClass( "mw-ui-button" ) ? $t.attr( "class" ) : "mw-ui-button" )
.on( "click", function(){ $t.trigger( "click" ); } ) );
signwriting_styled( $s[ 0 ] );
});
}); });