Adding RTL property to the page

Adding RTL property to the page

Hello,

I have been working on RTL support for jQuery Mobile and you asked on twitter how to make this more maintainable.

I suggest adding an RTL property to the page class/element; then check this property before setting any button/icon default positions and check it in sliders code as shown below; then make another RTL CSS file that overrides/reverses some values (floats, margins, text-direction.. etc) which users can simply link when RTL support is needed.

Here is my idea:

1) Make a property for RTL, I would make it a boolean and name it IsRTL or make it as an enumeration or a string and name it something like data-uidirection. The default value is false/ltr so it should be explicity set on the mark-up when RTL is needed, for example:

<div data-role="page" data-uidirection="rtl">
...
</div>

2) In jQuery JS file check the property in the slider code to make sliders and flip switches work properly, the value should be increased when dragging the handle to the LEFT or pressing the LEFT button and vice versa:

The switch statement on line 7792 may look like this:
  1. // move the slider according to the keypress
  2. // var isRtl = something like closest(".ui-page").attr("data-uidirection") == "rtl";
  3. switch (event.keyCode) {
  4.     case $.mobile.keyCode.HOME:
  5.         self.refresh(min);
  6.         break;
  7.     case $.mobile.keyCode.END:
  8.         self.refresh(min);
  9.         break;
  10.     case $.mobile.keyCode.PAGE_UP:
  11.     case $.mobile.keyCode.UP:
  12.         self.refresh(index + step);
  13.         break;
  14.     case $.mobile.keyCode.PAGE_DOWN:
  15.     case $.mobile.keyCode.DOWN:
  16.         self.refresh(index - step);
  17.         break;
  18.     case $.mobile.keyCode.RIGHT:
  19.         isRtl ? self.refresh(index - step) : self.refresh(index + step);
  20.         break;
  21.     case $.mobile.keyCode.LEFT:
  22.         isRtl ? self.refresh(index + step) : self.refresh(index - step);
  23.         break;
  24. }
For handle dragging, I guess its code on line 7860 and you can only subtract the percent from 100, like:
  1. // after percent = Math.round(((data.pageX - this.slider.offset().left) / this.slider.width()) * 100);
  2. if (isRtl) { percent = 100 - percent; }
Then finally on line 7901 check the property to decide which CSS to change:
  1. this.handle.css(isRtl ? "right" : "left", percent + "%");

3) Check the property before setting default button/icon positions to reverse the value:

Line 4807, if it is RTL the back button should be on the right and its arrow should be a right arrow:
  1. var btnPositionDirection = isRtl ? "right" : "left";
  2. var arrowPositionChar = isRtl ? "r" : "l";

  3. backBtn = $("<a href='javascript:void(0);' class='ui-btn-" + btnPositionDirection + "' data-" + $.mobile.ns + "rel='back' data-" + $.mobile.ns + "icon='arrow-" + arrowPositionChar + "'>" + o.backBtnText + "</a>")
Line 4995, default icon position should be 'right' when it is RTL:
  1. o.iconpos = o.iconpos || (isRtl ? "right" : "left"); 
Line 5252, default icon position:
  1. iconpos: $el.jqmData("iconpos") || o.iconPos || (isRtl ? "right" : "left")
Line 5494, default arrow on lists should be to the left when it is RTL:
  1. splitIcon: isRtl ? "arrow-l" : "arrow-r"
Lines 5684 and 5684:
  1. iconpos: isRtl ? "left" : "right",
  2. icon: a.length > 1 || icon === false ? false : icon || isRtl ? "arrow-l" : "arrow-r",
Line 7969, select menu icon position is left when it is RTL:
  1. iconpos: isRtl ? "left" : "right"

4) Make the CSS file that overrides/reverses some values that developers will link to when they need RTL, I would name it something like rtl.jquery.mobile-1.2.0.css, for example:
  1. /* original .ui-controlgroup .ui-btn-icon-notext .ui-btn-inner .ui-icon { position: absolute; top: 50%; right: 50%; margin: -9px -9px 0 0; } */
  2. .ui-controlgroup .ui-btn-icon-notext .ui-btn-inner .ui-icon {margin: -9px 0 0 -9px;}

  3. /* original .ui-footer .ui-navbar .ui-grid-d li.ui-block-e .ui-btn { margin-right: -4px; } */
  4. .ui-footer .ui-navbar .ui-grid-d li.ui-block-e .ui-btn { margin-left: -4px; }

  5. /* and so on, but DON'T reverse ui-btn-icon-left, ui-btn-icon-right, ui-btn-left, ui-btn-right */
I believe you can come up with better ways to do that. Regards.