- Author:
- David Nickerson <nickerso@users.sourceforge.net>
- Date:
- 2009-07-16 02:00:03+12:00
- Desc:
- the starting point for the HH tutorial example
- Permanent Source URI:
- https://models.fieldml.org/workspace/a1/rawfile/f6a8f90307388eb4b040ee3566b84d88b59247f7/dojo-presentation/js/dojo/dojox/string/BidiComplex.js
dojo.provide("dojox.string.BidiComplex");
dojo.experimental("dojox.string.BidiComplex");
// summary:
// BiDiComplex module handels complex expression issues known when using BiDi characters
// in File Paths, URLs, E-mail Address, XPATH, etc.
// this module adds property listeners to the text fields to correct the text representation
// in both static text and dynamic text during user input.
dojox.string.BidiComplex.attachInput = function(/*DOMNode*/field, /*String*/pattern){
// summary:
// Attach key listeners to the INPUT field to accomodate dynamic complex BiDi expressions
// field: INPUT DOM node
// pattern: Complex Expression Pattern type. One of "FILE_PATH", "URL", "EMAIL", "XPATH"
dojox.string.BidiComplex._ce_type = pattern; //FIXME: shared ref
field.alt = dojox.string.BidiComplex._ce_type;
if((document.dir == "rtl")||(document.body.dir == "rtl")){ //FIXME: use !dojo._isBodyLtr()?
field.style.textAlign = "right";
}
//FIXME: use dojo.connect
if(dojo.isIE){
field.onkeydown = new Function("dojox.string.BidiComplex._ceKeyDown(event);");
field.onkeyup = new Function("dojox.string.BidiComplex._ceKeyUp(event);");
}else{
field.onkeyup = dojox.string.BidiComplex._ceKeyUp;
field.onkeydown = dojox.string.BidiComplex._ceKeyDown;
}
//FIXME: use dojo.connect
field.oncut = dojox.string.BidiComplex._fOnCut;
field.oncopy = dojox.string.BidiComplex._fOnCopy;
field.value = dojox.string.BidiComplex._insertMarkers(field.value, field.alt);
};
dojox.string.BidiComplex.createDisplayString = function(/*String*/str, /*String*/pattern){
// summary:
// Create the display string by adding the Unicode direction Markers
// pattern: Complex Expression Pattern type. One of "FILE_PATH", "URL", "EMAIL", "XPATH"
//FIXME: inline _insertMarkers
return dojox.string.BidiComplex._insertMarkers(str, pattern);
};
dojox.string.BidiComplex.stripSpecialCharacters = function(str){
// summary:
// removes all Unicode directional markers from the string
return str.replace(/[\u200E\u200F\u202A-\u202E]/g, ""); // String
};
//FIXME: these statics are worrysome
dojox.string.BidiComplex._segmentsPointers = [];
dojox.string.BidiComplex._ce_type = null;
dojox.string.BidiComplex._PATH = null;
dojox.string.BidiComplex._insertAlways = false;
dojox.string.BidiComplex._fOnCut = new Function("dojox.string.BidiComplex._ceCutText(this)");
dojox.string.BidiComplex._fOnCopy = new Function("dojox.string.BidiComplex._ceCopyText(this);");
dojox.string.BidiComplex._ceKeyDown = function(event){
//FIXME: global references: obj and str0
obj = dojo.isIE ? event.srcElement : event.target;
str0 = obj.value;
};
dojox.string.BidiComplex._ceKeyUp = function(event){
var LRM = '\u200E';
//FIXME: str0 global reference
obj = dojo.isIE ? event.srcElement : event.target;
str1 = obj.value;
if(obj.alt != ""){
dojox.string.BidiComplex._ce_type = obj.alt;
}
ieKey = event.keyCode;
if((ieKey == dojo.keys.HOME)
|| (ieKey == dojo.keys.END)
|| (ieKey == dojo.keys.SHIFT)){
return;
}
var cursorStart, cursorEnd;
var selection = dojox.string.BidiComplex._getCaretPos(event, obj);
if(selection){
cursorStart = selection[0];
cursorEnd = selection[1];
}
//Jump over a cursor processing
if(dojo.isIE){
var cursorStart1 = cursorStart, cursorEnd1 = cursorEnd;
if(ieKey == dojo.keys.LEFT_ARROW){
if((str1.charAt(cursorEnd-1) == LRM)
&& (cursorStart == cursorEnd)){
dojox.string.BidiComplex._setSelectedRange(obj,cursorStart - 1, cursorEnd - 1);
}
return;
}
if(ieKey == dojo.keys.RIGHT_ARROW){
if(str1.charAt(cursorEnd-1) == LRM){
cursorEnd1 = cursorEnd + 1;
if(cursorStart == cursorEnd){
cursorStart1 = cursorStart + 1;
}
}
dojox.string.BidiComplex._setSelectedRange(obj, cursorStart1, cursorEnd1);
return;
}
}else{ //Firefox
if(ieKey == dojo.keys.LEFT_ARROW){
if(str1.charAt(cursorEnd-1) == LRM){
dojox.string.BidiComplex._setSelectedRange(obj, cursorStart - 1, cursorEnd - 1);
}
return;
}
if(ieKey == dojo.keys.RIGHT_ARROW){
if(str1.charAt(cursorEnd-1) == LRM){
dojox.string.BidiComplex._setSelectedRange(obj, cursorStart + 1, cursorEnd + 1);
}
return;
}
}
str2 = dojox.string.BidiComplex._insertMarkers(str1, obj.alt);
if(str1 != str2)
{
window.status = str1 + " c=" + cursorEnd;
obj.value = str2;
if((ieKey == dojo.keys.DELETE) && (str2.charAt(cursorEnd)==LRM)){
obj.value = str2.substring(0, cursorEnd) + str2.substring(cursorEnd+2, str2.length);
}
if(ieKey == dojo.keys.DELETE){
setSelectedRange(obj,cursorStart,cursorEnd);
}else if(ieKey == dojo.keys.BACKSPACE){
//FIXME: str0 global reference
if(str0.charAt(cursorEnd-1)==LRM){
dojox.string.BidiComplex._setSelectedRange(obj, cursorStart - 1, cursorEnd - 1);
}else{
dojox.string.BidiComplex._setSelectedRange(obj, cursorStart, cursorEnd);
}
}else if(obj.value.charAt(cursorEnd) != LRM){
dojox.string.BidiComplex._setSelectedRange(obj, cursorStart + 1, cursorEnd + 1);
}
}
};
dojox.string.BidiComplex._processCopy = function(obj, text, isReverse){
// summary:
// This function strips the unicode directional controls when the text copied to the Clipboard
if(text == null){
if(dojo.isIE){
range = document.selection.createRange();
text = range.text;
}else{
text = obj.value.substring(obj.selectionStart, obj.selectionEnd);
}
}
var textToClipboard = dojox.string.BidiComplex.stripSpecialCharacters(text);
if(dojo.isIE){
window.clipboardData.setData("Text", textToClipboard);
return true;
}else{
try {
return window.SignedJs.processCopy(textToClipboard); //FIXME: what's this?
}catch(e){ return false; }
}
};
dojox.string.BidiComplex._ceCopyText = function(obj){
if(dojo.isIE){
event.returnValue = false;
}
return dojox.string.BidiComplex._processCopy(obj, null, false);
};
dojox.string.BidiComplex._ceCutText = function(obj){
var ret = dojox.string.BidiComplex._processCopy(obj, null, false);
if(!ret){
return false;
}
if(dojo.isIE){
// curPos = obj.selectionStart;
range = document.selection.clear();
}else{
var curPos = obj.selectionStart;
obj.value = obj.value.substring(0, curPos) + obj.value.substring(obj.selectionEnd);
obj.setSelectionRange(curPos, curPos);
}
return true;
};
// is there dijit code to do this?
dojox.string.BidiComplex._getCaretPos = function(event, obj){
if(dojo.isIE){
var position = 0,
range = document.selection.createRange().duplicate(),
range2 = range.duplicate(),
rangeLength = range.text.length;
if(obj.type == "textarea"){
range2.moveToElementText(obj);
}else{
range2.expand('textedit');
}
while(range.compareEndPoints('StartToStart', range2) > 0){
range.moveStart('character', -1);
++position;
}
return [position, position + rangeLength];
}
return [event.target.selectionStart, event.target.selectionEnd];
};
// is there dijit code to do this?
dojox.string.BidiComplex._setSelectedRange = function(obj,selectionStart,selectionEnd){
if(dojo.isIE){
var range = obj.createTextRange();
if(range){
if(obj.type == "textarea"){
range.moveToElementText(obj);
}else{
range.expand('textedit');
}
range.collapse();
range.moveEnd('character', selectionEnd);
range.moveStart('character', selectionStart);
range.select();
}
}else{
obj.selectionStart = selectionStart;
obj.selectionEnd = selectionEnd;
}
};
dojox.string.BidiComplex._isBidiChar = function(c){
if(c >= '\u0030' && c <= '\u0039'){
return true;
}
return c > '\u00ff';
};
dojox.string.BidiComplex._isLatinChar = function(c){
return (c >= '\u0041' && c <= '\u005A') || (c >= '\u0061' && c <= '\u007A');
};
dojox.string.BidiComplex._isCharBeforeBiDiChar = function(buffer, i, previous){
if(dojox.string.BidiComplex._insertAlways){
return true;
}
while(i > 0){
if(i == previous){
return false;
}
i--;
if(dojox.string.BidiComplex._isBidiChar(buffer.charAt(i))){
return true;
}
if(dojox.string.BidiComplex._isLatinChar(buffer.charAt(i))){
return false;
}
}
return false;
};
dojox.string.BidiComplex._parse = function(/*String*/str, /*String*/pattern){
var i,i1;
var delimiters;
var previous = -1;
//erase segmentsPointers
if(dojox.string.BidiComplex._segmentsPointers != null){
for(i=0; i<dojox.string.BidiComplex._segmentsPointers.length; i++){ // FIXME: just whack array?
dojox.string.BidiComplex._segmentsPointers[i] = null;
}
}
var sp_len = 0;
if(pattern == "FILE_PATH"){
delimiters = "/\\:."; // FIXME: use split?
for(i = 0; i < str.length; i++){ //FIXME: dojo.forEach
if((delimiters.indexOf(str.charAt(i)) >= 0) &&
dojox.string.BidiComplex._isCharBeforeBiDiChar(str, i, previous)){
previous = i;
dojox.string.BidiComplex._segmentsPointers[sp_len++] = i;
}
}
}else if(pattern == "URL"){
var buffer_length = str.length;
// parse protocol, host, path
delimiters = "/:.?=&#"; // FIXME: use split?
for(i = 0; i < buffer_length; i++){ //FIXME: dojo.forEach
if((delimiters.indexOf(str.charAt(i)) >= 0) &&
dojox.string.BidiComplex._isCharBeforeBiDiChar(str, i, previous)){
previous = i;
dojox.string.BidiComplex._segmentsPointers[sp_len] = i;
sp_len++;
}
}
}else if(pattern == "EMAIL"){
delimiters = "<>@.,;"; // FIXME: use split?
var inQuotes = false;
for(i = 0; i < str.length; i++){ //FIXME: dojo.forEach
if(str.charAt(i) == '\"'){
if(dojox.string.BidiComplex._isCharBeforeBiDiChar(str, i, previous)){
previous = i;
dojox.string.BidiComplex._segmentsPointers[sp_len] = i;
sp_len++;
}
i++;
i1 = str.indexOf('\"', i);
if(i1 >= i){
i = i1;
}
if(dojox.string.BidiComplex._isCharBeforeBiDiChar(str, i, previous)){
previous = i;
dojox.string.BidiComplex._segmentsPointers[sp_len] = i;
sp_len++;
}
}
if((delimiters.indexOf(str.charAt(i)) >= 0) &&
dojox.string.BidiComplex._isCharBeforeBiDiChar(str, i, previous)){
previous = i;
dojox.string.BidiComplex._segmentsPointers[sp_len] = i;
sp_len++;
}
}
}else if(pattern == "XPATH"){
delimiters = "/\\:.<>=[]";
for (i = 0; i < str.length; i++){ //FIXME: dojo.forEach
if((delimiters.indexOf(str.charAt(i)) >= 0) &&
dojox.string.BidiComplex._isCharBeforeBiDiChar(str, i, previous)){
previous = i;
dojox.string.BidiComplex._segmentsPointers[sp_len] = i;
sp_len++;
}
}
}
return dojox.string.BidiComplex._segmentsPointers;
};
dojox.string.BidiComplex._insertMarkers = function(/*String*/str,/*String*/pattern){
str = dojox.string.BidiComplex.stripSpecialCharacters(str);
dojox.string.BidiComplex._segmentsPointers = dojox.string.BidiComplex._parse(str, pattern); // FIXME: shared ref
var buf = '\u202A'/*LRE*/ + str;
var shift = 1;
var n;
for(i = 0; i< dojox.string.BidiComplex._segmentsPointers.length; i++){ //FIXME: dojo.forEach
n = dojox.string.BidiComplex._segmentsPointers[i];
if(n != null){
preStr = buf.substring(0, n + shift);
postStr = buf.substring(n + shift, buf.length);
buf = preStr + '\u200E'/*LRM*/ + postStr;
shift++;
}
}
return buf;
};