A text has no "base direction" attribute. But what's wrong with simply
sending Hebrew text?
The problem is that mozilla doesn't detect the base direction, so when I write everything is aligned to the left - and even if I change the alignment manually using the toolbar (for HTML emails) it only sets the alignment - no option for setting the base direction.
Obviously, the wrong thing with that is that any punctuation/numbers/english within the hebrew text will not be aligned correctly.
Currently using Mozilla Thunderbird 0.3, but I believe the problem also exists in the current stable Mozilla Mail.
Sagi
Hi Sagi,
Someone on this list sent a set of macros for letting Mozilla do just that. They are hereby attached. Unfortunetly, I don't know who that someone was (can you please step forward?).
There are still some problems - Mozilla's BiDi editing is not free of problems. If you don't send your mail as HTML, the RTL attribute is lost. If you receive mail with no RTL settings, you need to hit "reply", and only then can you use these bindings. These problems, however, have moved Mozilla from "totally unusable for Hebrew" to "bearable, with no better alternative", at least as far as I'm concerned.
Personally, I think what kmail is doing is the worst possible. Kmail is "autodetecting" the directioness of the each paragraph based on the first character of that paragraph. There are two problems with this, both pretty grave.
A. There is no way to override this, in case I'm not happy. B. Kmail keeps this information to itself.
The result of B is that the only mail client that will display the message the same way as kmail will, is another kmail. Users of kmail tend to send out messages that are unreadable to anyone else.
Hope this helps,
Shachar
-- Shachar Shemesh Open Source integration & consulting Home page & resume - http://www.shemesh.biz/
mozBidiBindings 0.3
CHANGES IN 0.3
==============
- Support for API changes in Mozilla 1.3; may not work with older versions anymore.
CHANGES IN 0.2
==============
- Directionality changes now apply on selections too.
INSTALLAITON INSTRUCTIONS
=========================
1. Copy bidiBindings.xbl somewhere (e.g. to your home directory).
2. Add the following lines to your
~/.mozilla/PROFILE/*/chrome/userChrome.css file:
Replace PROFILE with the name of your Mozilla profile name.
Replace INSTALLDIR with the directory you've copied bidiBindings.xbl to.
input
{
-moz-binding: url("file:INSTALLDIR/bidiBindings.xbl#bidiInputFields")
!important;
}
editor
{
-moz-binding: url("file:INSTALLDIR/bidiBindings.xbl#bidiEditor") !important;
}
3. Add the following lines to your
~/.mozilla/PROFILE/*/chrome/userContent.css file:
Replace PROFILE with the name of your Mozilla profile name.
Replace INSTALLDIR with the directory you've copied bidiBindings.xbl to.
textarea, input[type=text], input[type=password], input:not([type]),
input:not([type=checkbox]):not([type=radio]):not([type=button]):not([type=image]):not([type=submit]):not([type=reset])
{
line-height: normal !important;
-moz-binding: url("file:INSTALLDIR/bidiBindings.xbl#bidiInputFields")
!important;
}
USAGE
=====
Ctrl-; for left-to-right directionality.
Ctrl-' for right-to-left directionality.
I know those are less than optimal keys, but its impossible to catch
Ctrl-Shift on Mozilla (so I can't do Windows-like keybindings) and
Ctrl-[ and Ctrl-] were taken.
The keybindings should work in input boxes, single line and multi-line,
(affecting the entire field) and the Composer / Mail Composer (affecting
the paragraphs / table cells / list items currently selected, or if nothing
is selected, the item the cursor is on).
<?xml version="1.0"?> <bindings id="htmlBindings" xmlns="http://www.mozilla.org/xbl" xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> <binding id="bidiInputFields" extends="resource:///res/builtin/platformHTMLBindings.xml#inputFields"> <handlers> <handler event="keypress" key=";" modifiers="control"> <![CDATA[ this.style.direction='ltr'; ]]> </handler> <handler event="keypress" key="'" modifiers="control"> <![CDATA[ this.style.direction='rtl'; ]]> </handler> </handlers> </binding> <binding id="bidiEditor" extends="chrome://global/content/bindings/editor.xml#editor"> <handlers> <handler event="keypress" key=";" modifiers="control"> <![CDATA[ function findClosestBlockElement(node) { // Try to locate the closest parent with display:block var v = node.ownerDocument.defaultView; while (node) { if (node.nodeType == ELEMENT_NODE) { var display = v.getComputedStyle(node, "").getPropertyValue('display'); if (display == 'block' || display == 'table-cell' || display == 'table-caption' || display == 'list-item') return node; } node = node.parentNode; } return node; } var editor = this.getHTMLEditor(this.contentWindow); if (!editor) { alert("Unable to control the editor. The API might have changed."); return; } if (editor.selection.rangeCount > 0) { for (i=0; i<editor.selection.rangeCount; ++i) { var range = editor.selection.getRangeAt(i); var node = range.startContainer; // walk the tree till we find the endContainer of the selection range, // giving our directionality style to everything on our way do { var closestBlockElement = findClosestBlockElement(node); if (closestBlockElement) closestBlockElement.style.direction = 'ltr'; else throw "Unable to find an block element to assign directionality to."; // This check should be placed here, not as the 'while' // condition, to handle cases where begin == end if (node == range.endContainer) break; if (node.firstChild) node = node.firstChild; else if (node.nextSibling) node = node.nextSibling; else // find a parent node which has anything after while (node = node.parentNode) { if (node.nextSibling) { node = node.nextSibling; break; } } } while(node); } } ]]> </handler> <handler event="keypress" key="'" modifiers="control"> <![CDATA[ function findClosestBlockElement(node) { // Try to locate the closest parent with display:block var v = node.ownerDocument.defaultView; while (node) { if (node.nodeType == ELEMENT_NODE) { var display = v.getComputedStyle(node, "").getPropertyValue('display'); if (display == 'block' || display == 'table-cell' || display == 'table-caption' || display == 'list-item') return node; } node = node.parentNode; } return node; } var editor = this.getHTMLEditor(this.contentWindow); if (!editor) { alert("Unable to control the editor. The API might have changed."); return; } if (editor.selection.rangeCount > 0) { for (i=0; i<editor.selection.rangeCount; ++i) { var range = editor.selection.getRangeAt(i); var node = range.startContainer; // walk the tree till we find the endContainer of the selection range, // giving our directionality style to everything on our way do { var closestBlockElement = findClosestBlockElement(node); if (closestBlockElement) closestBlockElement.style.direction = 'rtl'; else throw "Unable to find an block element to assign directionality to."; // This check should be placed here, not as the 'while' // condition, to handle cases where begin == end if (node == range.endContainer) break; if (node.firstChild) node = node.firstChild; else if (node.nextSibling) node = node.nextSibling; else // find a parent node which has anything after while (node = node.parentNode) { if (node.nextSibling) { node = node.nextSibling; break; } } } while(node); } } ]]> </handler> </handlers> </binding> </bindings>
