diff --git a/xpfe/browser/resources/content/navigator.js b/xpfe/browser/resources/content/navigator.js
index 93467ed92ca8..cf0d67a21b7b 100644
--- a/xpfe/browser/resources/content/navigator.js
+++ b/xpfe/browser/resources/content/navigator.js
@@ -660,6 +660,14 @@ function Startup()
gClickSelectsAll = pref.getBoolPref("browser.urlbar.clickSelectsAll");
gClickAtEndSelects = pref.getBoolPref("browser.urlbar.clickAtEndSelects");
+ // BiDi UI
+ gShowBiDi = isBidiEnabled();
+ if (gShowBiDi) {
+ document.getElementById("documentDirection-swap").hidden = false;
+ document.getElementById("textfieldDirection-separator").hidden = false;
+ document.getElementById("textfieldDirection-swap").hidden = false;
+ }
+
// now load bookmarks after a delay
setTimeout(LoadBookmarksCallback, 0);
}
@@ -2507,3 +2515,47 @@ function updateFileUploadItem()
else
item.setAttribute('disabled', 'true');
}
+
+function isBidiEnabled()
+{
+ var rv = false;
+
+ var systemLocale;
+ try {
+ var localeService = Components.classes["@mozilla.org/intl/nslocaleservice;1"]
+ .getService(Components.interfaces.nsILocaleService);
+ systemLocale = localeService.getSystemLocale().getCategory("NSILOCALE_CTYPE");
+ rv = /^(he|ar|syr|fa|ur)-/.test(systemLocale);
+ } catch (e) {}
+
+ if (!rv) {
+ // check the overriding pref
+ try {
+ rv = pref.getBoolPref("bidi.browser.ui");
+ }
+ catch (e) {}
+ }
+
+ return rv;
+}
+
+function SwitchDocumentDirection(aWindow)
+{
+ aWindow.document.dir = (aWindow.document.dir == "ltr" ? "rtl" : "ltr");
+
+ for (var run = 0; run < aWindow.frames.length; run++)
+ SwitchDocumentDirection(aWindow.frames[run]);
+}
+
+function SwitchFocusedTextEntryDirection()
+{
+ // The keybinding shoudn't work if the menu item is hidden
+ if (gShowBiDi) {
+ var focusedElement = document.commandDispatcher.focusedElement;
+ if (focusedElement)
+ if (window.getComputedStyle(focusedElement, "").direction == "ltr")
+ focusedElement.style.direction = "rtl";
+ else
+ focusedElement.style.direction = "ltr";
+ }
+}
diff --git a/xpfe/browser/resources/content/navigatorOverlay.xul b/xpfe/browser/resources/content/navigatorOverlay.xul
index c53be6afab6d..e56fbeafb8c7 100644
--- a/xpfe/browser/resources/content/navigatorOverlay.xul
+++ b/xpfe/browser/resources/content/navigatorOverlay.xul
@@ -86,7 +86,11 @@
-
+
+
@@ -154,6 +158,7 @@
+
@@ -164,7 +169,8 @@
-
+
+
@@ -374,6 +380,13 @@
+
+
+
@@ -409,6 +422,10 @@
+
diff --git a/xpfe/browser/resources/locale/en-US/navigator.dtd b/xpfe/browser/resources/locale/en-US/navigator.dtd
index d88ed8287a64..a0296a8db6ff 100644
--- a/xpfe/browser/resources/locale/en-US/navigator.dtd
+++ b/xpfe/browser/resources/locale/en-US/navigator.dtd
@@ -198,3 +198,8 @@
+
+
+
+
+
diff --git a/xpfe/communicator/resources/content/contentAreaContextOverlay.xul b/xpfe/communicator/resources/content/contentAreaContextOverlay.xul
index 78cb3bb55e51..5b5b46aa2e07 100644
--- a/xpfe/communicator/resources/content/contentAreaContextOverlay.xul
+++ b/xpfe/communicator/resources/content/contentAreaContextOverlay.xul
@@ -244,6 +244,15 @@
label="&metadataCmd.label;"
accesskey="&metadataCmd.accesskey;"
oncommand="gContextMenu.showMetadata();"/>
+
+
+
diff --git a/xpfe/communicator/resources/content/contentAreaUtils.js b/xpfe/communicator/resources/content/contentAreaUtils.js
index 7fbeb8928188..b8006dada3bf 100644
--- a/xpfe/communicator/resources/content/contentAreaUtils.js
+++ b/xpfe/communicator/resources/content/contentAreaUtils.js
@@ -843,3 +843,8 @@ function getCharsetforSave(aDocument)
return window.content.document.characterSet;
}
+
+function SwitchTextEntryDirection(aElement)
+{
+ aElement.dir = (window.getComputedStyle(aElement, "").direction == "ltr" ? "rtl" : "ltr");
+}
diff --git a/xpfe/communicator/resources/content/nsContextMenu.js b/xpfe/communicator/resources/content/nsContextMenu.js
index b575a0b5aff8..7bcdf438ae1b 100644
--- a/xpfe/communicator/resources/content/nsContextMenu.js
+++ b/xpfe/communicator/resources/content/nsContextMenu.js
@@ -48,6 +48,9 @@
| Currently, this code is relatively useless for any other purpose. In the |
| longer term, this code will be restructured to make it more reusable. |
------------------------------------------------------------------------------*/
+
+var gShowBiDi = false;
+
function nsContextMenu( xulMenu ) {
this.target = null;
this.menu = null;
@@ -200,6 +203,11 @@ nsContextMenu.prototype = {
this.showItem( "popupwindow-reject", this.popupURL && !blocking);
this.showItem( "popupwindow-allow", this.popupURL && blocking);
this.showItem( "context-sep-popup", this.popupURL);
+
+ // BiDi UI
+ this.showItem( "context-sep-bidi", gShowBiDi);
+ this.showItem( "context-bidi-text-direction-toggle", this.onTextInput && gShowBiDi);
+ this.showItem( "context-bidi-page-direction-toggle", !this.onTextInput && gShowBiDi);
},
initClipboardItems : function () {
diff --git a/xpfe/communicator/resources/content/utilityOverlay.js b/xpfe/communicator/resources/content/utilityOverlay.js
index 2db4ad6d0b36..b1efae0fdb83 100644
--- a/xpfe/communicator/resources/content/utilityOverlay.js
+++ b/xpfe/communicator/resources/content/utilityOverlay.js
@@ -382,6 +382,12 @@ function goUpdateGlobalEditMenuItems()
goUpdateCommand('cmd_paste');
goUpdateCommand('cmd_selectAll');
goUpdateCommand('cmd_delete');
+ try {
+ // XXX: implement controller for cmd_SwitchTextDirection
+ document.getElementById('cmd_SwitchTextDirection').setAttribute('disabled',
+ !document.commandDispatcher.focusedElement);
+ }
+ catch (e) {}
}
// update menu items that rely on the current selection
diff --git a/xpfe/communicator/resources/locale/en-US/contentAreaCommands.dtd b/xpfe/communicator/resources/locale/en-US/contentAreaCommands.dtd
index 8c37fd69fc86..50f36d59296b 100644
--- a/xpfe/communicator/resources/locale/en-US/contentAreaCommands.dtd
+++ b/xpfe/communicator/resources/locale/en-US/contentAreaCommands.dtd
@@ -87,3 +87,8 @@
+
+
+
+
+