I am developing a mobile application using jQuery and was looking for a solution for RTL languages support for jQuery Mobile. Unfortunately I found none. I had to do it my self. Please keep in mind that the file might not be complete, I have gradually updated it so that my application works. You might be using more components that needs further changes.
You can download the file from here
In case you still had any issues, the tips below helps you to fix the situation, I hope J.
- Add a direction attribute with “rtl” value to the body CSS
- Overwrite all css classes that has “float:right” with “float:left” and vise versa
- Overwrite all css classes that has “left:” with “right:” and vise versa. It is worth mentioning her that you keep the previous attribute and make it auto. Else it won’t work.
i.e. left:15px should be overwrite with left:auto;right:15px. - Do the same as point 3 for all classes that has margin-left, margin-right, padding-left and padding-right
That’s it, please enjoy it and let me know if you’ve any comments or questions
UPDATE: I stumbled upon another version for achieving this. I believe it’s more comprehensive than mine J. Please check http://stackoverflow.com/questions/6321271/jquery-mobile-right-to-left-css
Thanks, this seems to get work nicely.
I think you should also change text-align:left / text-align:right.
Also there is also short format of margin/padding.
Now I’m trying to write a tool to do this automatically…
Thanks I will take your comment.
Please let me know when your tool is ready
Try this code:
You pass is the css filename on the command line (i.e. test.css) and it created a file for RTL (test.RTL.css)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;
namespace RTL_CSS
{
// todo: check to see if works on minified CSS.
class Program
{
static void Main( string[] args )
{
foreach (var f in args)
{
var d=Path.ChangeExtension(Path.GetFileNameWithoutExtension(f)+”.RTL.”, Path.GetExtension(f));
d=Path.Combine(Path.GetDirectoryName(f), d);
RTL(f, d);
}
}
private const char MarkerChar=(char)0;
static private Regex ws=new Regex(@”\s*”);
private static void RTL( string s, string d )
{
var text=File.ReadAllText(s);
var transforms=GetTransforms();
var regex=CreateRegex(transforms);
var replaced=regex.Replace(text, ( m ) =>
{
string k = Normalize(m.Value);
string value;
if (transforms.TryGetValue(k, out value))
{
Console.WriteLine(m.Value+”=>”+value);
return value;
}
else
{
return m.Value;
}
});
File.WriteAllText(d, replaced);
}
private static string Normalize( string str )
{
return ws.Replace(str, “”).ToLower();
}
private static Regex CreateRegex( Dictionary transforms )
{
string regex=string.Join(“|”, transforms.Keys.Select(t => string.Format(“(?:{0})”, t.Replace(“:”, @”\s*:\s*”))));
regex=string.Format(“(?<![-a-zA-Z])({0})", regex);
return new Regex(regex);
}
private static Dictionary GetTransforms()
{
var n=new Dictionary{
{“float:right”,”float: left”},
{“float:left”,”float: right”},
{“left:”,”left:auto; right:”},
{“right:”,”right:auto; left:”},
{“text-align:left”,”text-align: right”},
{“text-align:right”,”text-align: left”},
{“margin-left:”,”margin-left:auto; margin-right:”},
{“margin-right:”,”margin-right:auto; margin-left:”},
{“padding-left:”,”padding-left:auto; padding-right:”},
{“padding-right:”,”padding-right:auto; padding-left:”},
};
// normalize keys.
return n.ToDictionary(v => Normalize(v.Key), v => v.Value);
}
}
}
There is my case I found that my code does not handle properly and that is the ui-header-fixed/ui-footer-fixed classes that specify both left & right attributes.
I use the following c# code to modify the css:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Text.RegularExpressions;
namespace ConvertJqueryMobileToRtl
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string cssContent = “”;
StreamReader rd = new StreamReader(“jquery.mobile-1.1.1.min.css”, Encoding.GetEncoding(1255));
cssContent = rd.ReadToEnd();
rd.Close();
cssContent = cssContent.Replace(“{“, “{\n”);
cssContent = cssContent.Replace(“;”, “;\n”);
cssContent = cssContent.Replace(“}”, “\n}\n\n”);
string[] lines = cssContent.Split(‘\n’);
StringBuilder sb = new StringBuilder();
foreach (string line in lines)
{
string line1 = line.Replace(“right:”, “temp:”);
line1 = line1.Replace(“right;”, “temp;”);
line1 = line1.Replace(“left:”, “right:”);
line1 = line1.Replace(“left;”, “right;”);
line1 = line1.Replace(“temp:”, “left:”);
line1 = line1.Replace(“temp;”, “left;”);
line1 = Regex.Replace(line1, @”padding:(\d+)px (\d+)px (\d+)px (\d+)px”, “padding:$1px $4px $3px $2px”);
sb.Append(line1);
}
cssContent = @”body{direction:rtl}
.ui-icon-arrow-r{background-position: -144px 50%;}
” + sb.ToString().Replace(“\n”, “”);
StreamWriter wr = new StreamWriter(“jquery.mobile-1.1.1.min.rtl.css”, false, Encoding.GetEncoding(1255));
wr.Write(cssContent);
wr.Close();
}
}
}
I’ll give it a try…
Thanks,
Nadav
Tomer,
I don’t think your code handles the float:and text-align attributes.
Also I does not handle margin.
Nadav
I changed the code to:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Text.RegularExpressions;
namespace ConvertJqueryMobileToRtl
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string cssContent = “”;
StreamReader rd = new StreamReader(“jquery.mobile-1.1.1.min.css”, Encoding.GetEncoding(1255));
cssContent = rd.ReadToEnd();
rd.Close();
cssContent = cssContent.Replace(“{“, “{\n”);
cssContent = cssContent.Replace(“;”, “;\n”);
cssContent = cssContent.Replace(“}”, “\n}\n\n”);
string[] lines = cssContent.Split(‘\n’);
StringBuilder sb = new StringBuilder();
foreach (string line in lines)
{
string line1 = line.Replace(“right:”, “temp:”);
line1 = line1.Replace(“right;”, “temp;”);
line1 = line1.Replace(“left:”, “right:”);
line1 = line1.Replace(“left;”, “right;”);
line1 = line1.Replace(“temp:”, “left:”);
line1 = line1.Replace(“temp;”, “left;”);
line1 = line1.Replace(“margin-right:”, “margin-temp:”);
line1 = line1.Replace(“margin-left:”, “margin-right:auto;margin-left:”);
line1 = line1.Replace(“margin-temp:”, “margin-left:auto;margin-right:”);
line1 = line1.Replace(“padding-right:”, “padding-temp:”);
line1 = line1.Replace(“padding-left:”, “padding-right:auto;padding-left:”);
line1 = line1.Replace(“padding-temp:”, “padding-left:auto;padding-right:”);
line1 = Regex.Replace(line1, @”padding:(\d+)px (\d+)px (\d+)px (\d+)px”, “padding:$1px $4px $3px $2px”);
sb.Append(line1);
}
cssContent = @”body{direction:rtl}
.ui-icon-arrow-r{background-position: -144px 50%;}
” + sb.ToString().Replace(“\n”, “”);
StreamWriter wr = new StreamWriter(“jquery.mobile-1.1.1.min.rtl.css”, false, Encoding.GetEncoding(1255));
wr.Write(cssContent);
wr.Close();
}
}
}
Now, to me, it works just fine…
does it work for version 1.3.0 ?
Not 100% will try in a couple of weeks and confirm
Panel transitions not working well. It start from the middle towards the left or right side instead of starting from the side (left or right) towards the middle…
After some more checking I noticed that “ui-responsive-panel” does not handle correctly in my code, sorry…
I changed the code. It is not “nice”, but now panel transitions works well. Try it…
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Text.RegularExpressions;
namespace ConvertJqueryMobileToRtl
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string cssContent = “”;
StreamReader rd = new StreamReader(“jquery.mobile-1.3.0.min.css”, Encoding.GetEncoding(1255));
cssContent = rd.ReadToEnd();
rd.Close();
cssContent = cssContent.Replace(“{“, “{\n”);
cssContent = cssContent.Replace(“;”, “;\n”);
cssContent = cssContent.Replace(“}”, “\n}\n\n”);
string[] lines = cssContent.Split(‘\n’);
StringBuilder sb = new StringBuilder();
bool wastranslate3d = false;
bool stopRTL = false;
foreach (string line in lines)
{
if (line.Contains(“-webkit-transform:translate3d(0,0,0)”))
wastranslate3d = true;
if (line.Contains(“.ui-panel-position-left”) && wastranslate3d)
{
stopRTL = true;
}
if (stopRTL)
{
sb.Append(line);
}
else
{
string line1 = line.Replace(“right:”, “temp:”);
line1 = line1.Replace(“right;”, “temp;”);
line1 = line1.Replace(“left:”, “right:”);
line1 = line1.Replace(“left;”, “right;”);
line1 = line1.Replace(“temp:”, “left:”);
line1 = line1.Replace(“temp;”, “left;”);
line1 = line1.Replace(“margin-right:”, “margin-temp:”);
line1 = line1.Replace(“margin-left:”, “margin-right:auto;margin-left:”);
line1 = line1.Replace(“margin-temp:”, “margin-left:auto;margin-right:”);
line1 = line1.Replace(“padding-right:”, “padding-temp:”);
line1 = line1.Replace(“padding-left:”, “padding-right:auto;padding-left:”);
line1 = line1.Replace(“padding-temp:”, “padding-left:auto;padding-right:”);
line1 = Regex.Replace(line1, @”padding:(\d+)px (\d+)px (\d+)px (\d+)px”, “padding:$1px $4px $3px $2px”);
sb.Append(line1);
}
}
cssContent = @”body{direction:rtl}
.ui-icon-arrow-r{background-position: -144px 50%;}
” + sb.ToString().Replace(“\n”, “”);
StreamWriter wr = new StreamWriter(“jquery.mobile-1.3.0.min.rtl.css”, false, Encoding.GetEncoding(1255));
wr.Write(cssContent);
wr.Close();
}
}
}
One more correction to handle “ui-responsive-panel” :
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Text.RegularExpressions;
namespace ConvertJqueryMobileToRtl
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string cssContent = “”;
StreamReader rd = new StreamReader(“jquery.mobile-1.3.0.min.css”, Encoding.GetEncoding(1255));
cssContent = rd.ReadToEnd();
rd.Close();
cssContent = cssContent.Replace(“{“, “{\n”);
cssContent = cssContent.Replace(“;”, “;\n”);
cssContent = cssContent.Replace(“}”, “\n}\n\n”);
string[] lines = cssContent.Split(‘\n’);
StringBuilder sb = new StringBuilder();
bool wastranslate3d = false;
bool stopRTL = false;
bool doMargin = false;
foreach (string line in lines)
{
if (line.Contains(“-webkit-transform:translate3d(0,0,0)”))
wastranslate3d = true;
if (line.Contains(“.ui-panel-position-left”) && wastranslate3d)
{
stopRTL = true;
}
if (stopRTL)
{
if (line.Contains(“.ui-responsive-panel.”))
doMargin = true;
if (doMargin)
{
string line1 = line.Replace(“margin-right:”, “margin-temp:”);
line1 = line1.Replace(“margin-left:”, “margin-right:”);
line1 = line1.Replace(“margin-temp:”, “margin-left:”);
sb.Append(line1);
}
else
sb.Append(line);
}
else
{
string line1 = line.Replace(“right:”, “temp:”);
line1 = line1.Replace(“right;”, “temp;”);
line1 = line1.Replace(“left:”, “right:”);
line1 = line1.Replace(“left;”, “right;”);
line1 = line1.Replace(“temp:”, “left:”);
line1 = line1.Replace(“temp;”, “left;”);
line1 = line1.Replace(“margin-right:”, “margin-temp:”);
line1 = line1.Replace(“margin-left:”, “margin-right:auto;margin-left:”);
line1 = line1.Replace(“margin-temp:”, “margin-left:auto;margin-right:”);
line1 = line1.Replace(“padding-right:”, “padding-temp:”);
line1 = line1.Replace(“padding-left:”, “padding-right:auto;padding-left:”);
line1 = line1.Replace(“padding-temp:”, “padding-left:auto;padding-right:”);
line1 = Regex.Replace(line1, @”padding:(\d+)px (\d+)px (\d+)px (\d+)px”, “padding:$1px $4px $3px $2px”);
sb.Append(line1);
}
}
cssContent = @”body{direction:rtl}
.ui-icon-arrow-r{background-position: -144px 50%;}
” + sb.ToString().Replace(“\n”, “”);
StreamWriter wr = new StreamWriter(“jquery.mobile-1.3.0.min.rtl.css”, false, Encoding.GetEncoding(1255));
wr.Write(cssContent);
wr.Close();
}
}
}
Excellent program! Well done 🙂
Thank you. It works.