jquery-ui: BTD support 1

This commit is contained in:
Alex Shensis 2017-06-13 14:22:40 +03:00
parent 74f8a0ac95
commit 254fd68bdc
21 changed files with 152 additions and 5 deletions

View File

@ -21,6 +21,7 @@ common.testWidget( "accordion", {
"activeHeader": "ui-icon-triangle-1-s", "activeHeader": "ui-icon-triangle-1-s",
"header": "ui-icon-triangle-1-e" "header": "ui-icon-triangle-1-e"
}, },
textDir: null,
// Callbacks // Callbacks
activate: null, activate: null,

View File

@ -21,6 +21,7 @@ common.testWidget( "autocomplete", {
collision: "none" collision: "none"
}, },
source: null, source: null,
textDir: null,
// Callbacks // Callbacks
change: null, change: null,

View File

@ -18,6 +18,7 @@ common.testWidget( "button", {
label: null, label: null,
showLabel: true, showLabel: true,
text: true, text: true,
textDir: null,
// Callbacks // Callbacks
create: null create: null

View File

@ -13,6 +13,7 @@ common.testWidget( "button", {
iconPosition: "beginning", iconPosition: "beginning",
label: null, label: null,
showLabel: true, showLabel: true,
textDir: null,
// Callbacks // Callbacks
create: null create: null

View File

@ -13,6 +13,7 @@ common.testWidget( "checkboxradio", {
disabled: null, disabled: null,
icon: true, icon: true,
label: null, label: null,
textDir: null,
// Callbacks // Callbacks
create: null create: null

View File

@ -20,6 +20,7 @@ common.testWidget( "controlgroup", {
"controlgroupLabel": ".ui-controlgroup-label" "controlgroupLabel": ".ui-controlgroup-label"
}, },
onlyVisible: true, onlyVisible: true,
textDir: null,
// Callbacks // Callbacks
create: null create: null

View File

@ -17,6 +17,7 @@ common.testWidget( "menu", {
at: "right top" at: "right top"
}, },
role: "menu", role: "menu",
textDir: null,
// Callbacks // Callbacks
blur: null, blur: null,

View File

@ -19,6 +19,7 @@ common.testWidget( "selectmenu", {
at: "left bottom", at: "left bottom",
collision: "none" collision: "none"
}, },
textDir: null,
width: false, width: false,
// Callbacks // Callbacks

View File

@ -18,6 +18,7 @@ common.testWidget( "tabs", {
heightStyle: "content", heightStyle: "content",
hide: null, hide: null,
show: null, show: null,
textDir: null,
// Callbacks // Callbacks
activate: null, activate: null,

View File

@ -18,6 +18,7 @@ common.testWidget( "tooltip", {
collision: "flipfit flip" collision: "flipfit flip"
}, },
show: true, show: true,
textDir: null,
tooltipClass: null, tooltipClass: null,
track: false, track: false,

View File

@ -18,6 +18,7 @@ common.testWidget( "tooltip", {
collision: "flipfit flip" collision: "flipfit flip"
}, },
show: true, show: true,
textDir: null,
track: false, track: false,
// Callbacks // Callbacks

View File

@ -697,6 +697,32 @@ $.Widget.prototype = {
return !( $.isFunction( callback ) && return !( $.isFunction( callback ) &&
callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false || callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
event.isDefaultPrevented() ); event.isDefaultPrevented() );
},
_getTextDir: function( text ) {
if ( this.options.textDir === "auto" ) {
// Look for first strong (either English or Arabic/Hebrew) character
// Resolve text direction accordingly ("rtl" for Arabic/Hebrew, "ltr" otherwise)
var matcher = /[A-Za-z\u05d0-\u065f\u066a-\u06ef\u06fa-\u07ff\ufb1d-\ufdff\ufe70-\ufefc]/.exec( text );
return ( matcher && ( matcher[ 0 ] > "z" ) ) ? "rtl" : "ltr";
}
return this.options.textDir;
},
_applyTextDir: function( param ) {
if ( typeof param === "string" ) {
param = param.replace( /[\u202A\u202B\u202C]/g, "" );
// Unicode directional characters: 202A and 202B used to enforce text direction
// 202C - POP formatter closing directional segment
return ( this._getTextDir( param ) === "rtl" ? "\u202B" : "\u202A" ) + param + "\u202C";
} else if ( param.jquery ) {
var isField = param.is( "input" ) || param.is( "textarea" );
param.css( "direction", this._getTextDir( isField ? param.val() : param.text() ) );
} else if ( param.nodeType === 1 ) {
param.style.direction = this._getTextDir( param.textContent );
}
} }
}; };

View File

@ -54,6 +54,7 @@ return $.widget( "ui.accordion", {
activeHeader: "ui-icon-triangle-1-s", activeHeader: "ui-icon-triangle-1-s",
header: "ui-icon-triangle-1-e" header: "ui-icon-triangle-1-e"
}, },
textDir: null,
// Callbacks // Callbacks
activate: null, activate: null,
@ -305,6 +306,13 @@ return $.widget( "ui.accordion", {
this._addClass( this.active.next(), "ui-accordion-content-active" ); this._addClass( this.active.next(), "ui-accordion-content-active" );
this.active.next().show(); this.active.next().show();
if ( this.options.textDir ) {
var that = this;
this.headers.each( function( i, header ) {
header.textContent = that._applyTextDir( header.textContent );
} );
}
this.headers this.headers
.attr( "role", "tab" ) .attr( "role", "tab" )
.each( function() { .each( function() {

View File

@ -50,6 +50,7 @@ $.widget( "ui.autocomplete", {
collision: "none" collision: "none"
}, },
source: null, source: null,
textDir: null,
// Callbacks // Callbacks
change: null, change: null,
@ -89,6 +90,26 @@ $.widget( "ui.autocomplete", {
this._addClass( "ui-autocomplete-input" ); this._addClass( "ui-autocomplete-input" );
this.element.attr( "autocomplete", "off" ); this.element.attr( "autocomplete", "off" );
if ( this.options.textDir ) {
var textDir = this._getTextDir( this._value() );
this.element.css( "direction", textDir );
if ( this.options.textDir === "auto" ) {
this.element.css( "text-align", textDir === "rtl" ? "right" : "left" );
this._on( this.element, {
keyup: function( e ) {
var keyCode = $.ui.keyCode;
if ( e.keyCode < keyCode.PAGE_UP || e.keyCode >= keyCode.DELETE ) {
var textDir = this._getTextDir( this._value() );
this.element.css( "direction", textDir )
.css( "text-align", textDir === "rtl" ? "right" : "left" );
}
}
} );
} else {
this.element.css( "text-align",
this.element.css( "direction" ) === "rtl" ? "right" : "left" );
}
}
this._on( this.element, { this._on( this.element, {
keydown: function( event ) { keydown: function( event ) {
@ -288,6 +309,9 @@ $.widget( "ui.autocomplete", {
if ( false !== this._trigger( "select", event, { item: item } ) ) { if ( false !== this._trigger( "select", event, { item: item } ) ) {
this._value( item.value ); this._value( item.value );
if ( this.options.textDir === "auto" ) {
this.element.css( "direction", this._getTextDir( item.value ) );
}
} }
// reset the term after the select event // reset the term after the select event
@ -521,6 +545,15 @@ $.widget( "ui.autocomplete", {
_suggest: function( items ) { _suggest: function( items ) {
var ul = this.menu.element.empty(); var ul = this.menu.element.empty();
this._renderMenu( ul, items ); this._renderMenu( ul, items );
if ( this.options.textDir ) {
ul.css( "text-align", ul.css( "direction" ) === "rtl" ? "right" : "left" );
var that = this;
ul.children().each( function( i, li ) {
li.style.direction = that._getTextDir( li.textContent );
} );
}
this.isNewMenu = true; this.isNewMenu = true;
this.menu.refresh(); this.menu.refresh();

View File

@ -49,7 +49,8 @@ $.widget( "ui.button", {
icon: null, icon: null,
iconPosition: "beginning", iconPosition: "beginning",
label: null, label: null,
showLabel: true showLabel: true,
textDir: null
}, },
_getCreateOptions: function() { _getCreateOptions: function() {
@ -96,6 +97,14 @@ $.widget( "ui.button", {
this.element.html( this.options.label ); this.element.html( this.options.label );
} }
} }
if ( this.options.textDir ) {
this._applyTextDir( this.element );
if ( this.hasTitle ) {
this.element.attr( "title", this._applyTextDir( this.element.attr( "title" ) ) );
}
}
this._addClass( "ui-button", "ui-widget" ); this._addClass( "ui-button", "ui-widget" );
this._setOption( "disabled", this.options.disabled ); this._setOption( "disabled", this.options.disabled );
this._enhance(); this._enhance();
@ -218,6 +227,9 @@ $.widget( "ui.button", {
options.showLabel = true; options.showLabel = true;
} }
this._super( options ); this._super( options );
if ( ( this.options.textDir && options.label ) || options.textDir ) {
this._applyTextDir( this.element );
}
}, },
_setOption: function( key, value ) { _setOption: function( key, value ) {

View File

@ -44,7 +44,8 @@ $.widget( "ui.checkboxradio", [ $.ui.formResetMixin, {
classes: { classes: {
"ui-checkboxradio-label": "ui-corner-all", "ui-checkboxradio-label": "ui-corner-all",
"ui-checkboxradio-icon": "ui-corner-all" "ui-checkboxradio-icon": "ui-corner-all"
} },
textDir: null
}, },
_getCreateOptions: function() { _getCreateOptions: function() {
@ -105,6 +106,13 @@ $.widget( "ui.checkboxradio", [ $.ui.formResetMixin, {
this._addClass( this.label, "ui-checkboxradio-radio-label" ); this._addClass( this.label, "ui-checkboxradio-radio-label" );
} }
if ( this.options.textDir ) {
var markup = $.parseHTML( this.options.label );
if ( markup && markup.length === 1 && markup[ 0 ].nodeType === 3 ) {
this.options.label = this._applyTextDir( this.options.label );
}
}
if ( this.options.label && this.options.label !== this.originalLabel ) { if ( this.options.label && this.options.label !== this.originalLabel ) {
this._updateLabel(); this._updateLabel();
} else if ( this.originalLabel ) { } else if ( this.originalLabel ) {
@ -208,6 +216,13 @@ $.widget( "ui.checkboxradio", [ $.ui.formResetMixin, {
this._super( key, value ); this._super( key, value );
if ( this.options.textDir && ( key === "label" || key === "textDir" ) ) {
var markup = $.parseHTML( this.options.label );
if ( markup && markup.length === 1 && markup[ 0 ].nodeType === 3 ) {
this.options.label = this._applyTextDir( this.options.label );
}
}
if ( key === "disabled" ) { if ( key === "disabled" ) {
this._toggleClass( this.label, null, "ui-state-disabled", value ); this._toggleClass( this.label, null, "ui-state-disabled", value );
this.element[ 0 ].disabled = value; this.element[ 0 ].disabled = value;

View File

@ -45,7 +45,8 @@ return $.widget( "ui.controlgroup", {
"checkboxradio": "input[type='checkbox'], input[type='radio']", "checkboxradio": "input[type='checkbox'], input[type='radio']",
"selectmenu": "select", "selectmenu": "select",
"spinner": ".ui-spinner-input" "spinner": ".ui-spinner-input"
} },
textDir: null
}, },
_create: function() { _create: function() {
@ -92,8 +93,11 @@ return $.widget( "ui.controlgroup", {
if ( element.children( ".ui-controlgroup-label-contents" ).length ) { if ( element.children( ".ui-controlgroup-label-contents" ).length ) {
return; return;
} }
element.contents() var dir = that.options.textDir ?
.wrapAll( "<span class='ui-controlgroup-label-contents'></span>" ); "dir='" + that._getTextDir( element.text() ) + "' " : "";
element.contents().wrapAll(
"<span " + dir + "class='ui-controlgroup-label-contents'></span>" );
} ); } );
that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" ); that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" );
childWidgets = childWidgets.concat( labels.get() ); childWidgets = childWidgets.concat( labels.get() );
@ -138,6 +142,9 @@ return $.widget( "ui.controlgroup", {
instanceOptions.classes = instanceOptions.classes =
that._resolveClassesValues( instanceOptions.classes, instance ); that._resolveClassesValues( instanceOptions.classes, instance );
} }
if ( that.options.textDir ) {
instanceOptions.textDir = that.options.textDir;
}
element[ widget ]( instanceOptions ); element[ widget ]( instanceOptions );
// Store an instance of the controlgroup to be able to reference // Store an instance of the controlgroup to be able to reference

View File

@ -51,6 +51,7 @@ return $.widget( "ui.menu", {
at: "right top" at: "right top"
}, },
role: "menu", role: "menu",
textDir: null,
// Callbacks // Callbacks
blur: null, blur: null,
@ -370,6 +371,16 @@ return $.widget( "ui.menu", {
if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
this.blur(); this.blur();
} }
if ( this.options.textDir ) {
menus.each( function() {
var item = $( this );
item.css( "text-align", item.css( "direction" ) === "rtl" ? "right" : "left" );
} );
items.each( function() {
that._applyTextDir( this );
} );
}
}, },
_itemRole: function() { _itemRole: function() {

View File

@ -60,6 +60,7 @@ return $.widget( "ui.selectmenu", [ $.ui.formResetMixin, {
collision: "none" collision: "none"
}, },
width: false, width: false,
textDir: null,
// Callbacks // Callbacks
change: null, change: null,
@ -318,6 +319,10 @@ return $.widget( "ui.selectmenu", [ $.ui.formResetMixin, {
var that = this, var that = this,
currentOptgroup = ""; currentOptgroup = "";
if ( this.options.textDir ) {
ul.css( "text-align", ul.css( "direction" ) === "rtl" ? "right" : "left" );
}
$.each( items, function( index, item ) { $.each( items, function( index, item ) {
var li; var li;
@ -359,6 +364,9 @@ return $.widget( "ui.selectmenu", [ $.ui.formResetMixin, {
_setText: function( element, value ) { _setText: function( element, value ) {
if ( value ) { if ( value ) {
if ( this.options.textDir ) {
value = this._applyTextDir( value );
}
element.text( value ); element.text( value );
} else { } else {
element.html( "&#160;" ); element.html( "&#160;" );

View File

@ -52,6 +52,7 @@ $.widget( "ui.tabs", {
heightStyle: "content", heightStyle: "content",
hide: null, hide: null,
show: null, show: null,
textDir: null,
// Callbacks // Callbacks
activate: null, activate: null,
@ -371,6 +372,13 @@ $.widget( "ui.tabs", {
"aria-hidden": "true" "aria-hidden": "true"
} ); } );
if ( this.options.textDir ) {
var that = this;
this.tabs.each( function( i, tab ) {
that._applyTextDir( $( tab ).find( ".ui-tabs-anchor" ) );
} );
}
// Make sure one tab is in the tab order // Make sure one tab is in the tab order
if ( !this.active.length ) { if ( !this.active.length ) {
this.tabs.eq( 0 ).attr( "tabIndex", 0 ); this.tabs.eq( 0 ).attr( "tabIndex", 0 );

View File

@ -61,6 +61,7 @@ $.widget( "ui.tooltip", {
}, },
show: true, show: true,
track: false, track: false,
textDir: null,
// Callbacks // Callbacks
close: null, close: null,
@ -265,6 +266,9 @@ $.widget( "ui.tooltip", {
tooltipData = this._find( target ); tooltipData = this._find( target );
if ( tooltipData ) { if ( tooltipData ) {
tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content ); tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
if ( this.options.textDir ) {
this._applyTextDir( tooltipData.tooltip.find( ".ui-tooltip-content" ) );
}
return; return;
} }
@ -288,6 +292,10 @@ $.widget( "ui.tooltip", {
this._addDescribedBy( target, tooltip.attr( "id" ) ); this._addDescribedBy( target, tooltip.attr( "id" ) );
tooltip.find( ".ui-tooltip-content" ).html( content ); tooltip.find( ".ui-tooltip-content" ).html( content );
if ( this.options.textDir ) {
this._applyTextDir( tooltip.find( ".ui-tooltip-content" ) );
}
// Support: Voiceover on OS X, JAWS on IE <= 9 // Support: Voiceover on OS X, JAWS on IE <= 9
// JAWS announces deletions even when aria-relevant="additions" // JAWS announces deletions even when aria-relevant="additions"
// Voiceover will sometimes re-read the entire log region's contents from the beginning // Voiceover will sometimes re-read the entire log region's contents from the beginning