12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250 |
- // Licensed Materials - Property of IBM
- // IBM Cognos Products: cclcore
- // (C) Copyright IBM Corp. 2012
- // US Government Users Restricted Rights – Use, duplication or disclosure restricted
- // by GSA ADP Schedule Contract with IBM Corp.
- //
- // Common bidi javascript library - BidiUtils.
- // Singleton containing useable bidi methods.
- function BidiUtils(){
- this.baseTextDirection = "ltr";
- this.guiOrientation = "ltr";
- this.productLocale = "en";
- this.LRM = '\u200E';
- this.RLM = '\u200F';
- this.LRE = '\u202A';
- this.RLE = '\u202B';
- this.PDF = '\u202C';
- this.ZWNJ= '\u200C';
- this.BACKREF = '$1';
- this.BACKREF_PDF = '\u202C$1';
- this.caretPos = null;
- this.LTR_DIR=1;
- this.RTL_DIR=2;
- this.multiemail="multiemail";
- this._K_BACK = 0x8;
- this._K_SHIFT = 0x10;
- this._K_END = 0x23;
- this._K_HOME = 0x24;
- this._K_LEFT = 0x25;
- this._K_RIGHT = 0x27;
- this._K_DELETE = 0x2e;
- this._K_PAGEUP = 0x21;
- this._K_PAGEDOWN = 0x22;
- this._K_UP = 0x26;
- this._K_DOWN = 0x28;
- this._K_ENTER = 0xD;
- this._K_ESC = 0x1B;
- this._K_INSERT = 0x2D;
- this.isIE = navigator.userAgent.indexOf("MSIE") >=0;
- this.isFF = navigator.userAgent.toLowerCase().indexOf("firefox") >=0;
- };
- BidiUtils.instance = null;
- // This function returns the singleton instance of BidiUtils.
- BidiUtils.getInstance = function(){
- if (BidiUtils.instance == null){
- BidiUtils.instance = new BidiUtils();
- }
- return BidiUtils.instance;
- };
- // The function is used to set properties, needed for correct work of singleton methods.
- // @bTextDir: base text direction
- // @orient: orientation of the current page
- // @pLocale: the locale (product language)
- BidiUtils.prototype.setProperties = function(bTextDir, orient, pLocale){
- if (bTextDir){
- this.baseTextDirection = bTextDir;
- }
- if (orient){
- this.guiOrientation = orient;
- }
- if (pLocale){
- this.productLocale = pLocale;
- }
- };
- // The function is used to add bidi specific handler for focus event, which in its turn
- // is used to add all event handlers, needed for given element
- // in accordance with its type and specifics.
- // @objOrId: element or its id.
- BidiUtils.prototype.attachAllListeners = function(objOrId){
- var object = document.getElementById(objOrId);
- this._patchMethod(object,"onfocus");
- };
- // The function is the bidi-specific handler for focus event.
- // First call of this function allows to add all event handlers, needed for given element
- // in accordance with its type and specifics.
- // @object: element, whose onfocus handler should be added or updated
- BidiUtils.prototype.onfocus = function(object,event){
- if (!object.isHandled){
- object.isHandled = true;
- if (object.attributes["stttype"]){
- object.stttype = object.attributes["stttype"].nodeValue;
- }
- this._attachListeners(object);
- }
- };
- // The function is used to add for given element all bidi-specific handlers.
- // @object: element that we need to add bidi-specific handlers
- BidiUtils.prototype._attachListeners = function(object){
- if (!object.stttype){
- if (this.baseTextDirection == "auto"){
- this._patchMethod(object,"onkeyup");
- }
- }
- else {
- if (typeof this["_parse_" + object.stttype] !== "function"){
- console.log("Can't add listeners for object, which name is " + object.name + ": parser for STT " + object.stttype + " isn't defined");
- return;
- }
- this._patchMethod(object,"onkeyup");
- this._patchMethod(object,"onkeydown");
- this._patchMethod(object,"oncopy");
- this._patchMethod(object,"onpaste");
- this._patchMethod(object,"oncut");
- this._patchMethod(object,"onmousedown");
- }
- };
- BidiUtils.prototype._patchMethod = function(object,method){
- var oldMethod = object[method];
- var self = this;
- object[method] = function(event){
- self[method](object,event);
- if (oldMethod && typeof oldMethod === "function"){
- oldMethod.apply(object, arguments);
- }
- };
- };
- // The function is the bidi-specific handler for keyup event.
- // @object: element, whose onkeyup handler should be added or updated
- // @event: keyup event object
- BidiUtils.prototype.onkeyup = function(object,event){
- if (!object.stttype){
- object.dir = this.resolveStrBtd(object.value);
- }
- else{
- this._handleKey(object,event);
- }
- };
- // The function is the bidi-specific handler for keyup event.
- // @object: element, whose onkeyup handler should be added or updated
- // @event: keydown event object
- BidiUtils.prototype.onkeydown = function(object,event){
- if (!object.stttype){
- return;
- }
- this._processBackspaceDelete(object,event);
- };
- // The function is the bidi-specific handler for mousedown event.
- // @object: element, whose onmousedown handler should be added or updated
- // @event: event object
- BidiUtils.prototype.onmousedown = function(object,event){
- if (!object.stttype){
- return;
- }
- if (this.isIE){
- event = window.event;
- }
- this._adjustCaret(object,event,null);
- };
- // The function is the bidi-specific handler for copy event.
- // @object: element, whose oncopy handler should be added or updated
- // @event: event object
- BidiUtils.prototype.oncopy = function(object,event){
- if (!object.stttype){
- return;
- }
- this._processCopy(object,event);
- };
- // The function is the bidi-specific handler for paste event.
- // @object: element, whose onpaste handler should be added or updated
- // @event: event object
- BidiUtils.prototype.onpaste = function(object,event){
- if (!object.stttype){
- return;
- }
- this._processPaste(object,event);
- };
- // The function is the bidi-specific handler for cut event.
- // @object: element, whose oncut handler should be added or updated
- // @event: event object
- BidiUtils.prototype.oncut = function(object,event){
- if (!object.stttype){
- return;
- }
- this._processCut(object,event);
- };
- // The function is the bidi-specific handler for submit event.
- // It removes bidi markers (UCC) from values of the text fields,
- // which are placed in the given form and contain structured text.
- // @form: form containing text fields, values of which should be handled
- BidiUtils.prototype.onsubmit = function(form){
- var nType = ["input","textarea"];
- var nList;
- for (var i=0; i<2; i++){
- nList = form.getElementsByTagName(nType[i]);
- for (var i=0; i<nList.length; i++){
- var object = nList[i];
- if (object && object.attributes["stttype"]){
- object.value = this.removeUCCFromStr(object.value);
- }
- }
- }
- return true;
- };
- // The function is used to determine base direction of the given text.
- // @text: analyzed text
- BidiUtils.prototype.resolveStrBtd = function(text){
- var len = text.length;
- for(var i = 0;i < len;i++) {
- symbol = text.charCodeAt(i);
- if(this._isBidiChar(symbol))
- return "rtl";
- else if(this._isLatinChar(symbol))
- return "ltr";
- }
- return this.guiOrientation;
- };
- // The function injects UCC into the given string in accordance with the
- // given base text direction.
- // @text: text without UCC
- // @btd: base text direction
- BidiUtils.prototype.btdInjectUCCIntoStr = function(text, btd){
- if (typeof btd == "undefined"){
- btd = this.baseTextDirection;
- }
- if (btd == "auto"){
- btd = this.resolveStrBtd(text);
- }
- if (btd == "rtl"){
- return this.RLE + text + this.PDF;
- }
- else{
- return this.LRE + text + this.PDF;
- }
- };
- // The function sets dir attribute of the given element in accordance with the
- // given base text direction.
- // @objOrId: element or its id.
- // @btd: base text direction
- BidiUtils.prototype.btdSetDir = function(objOrDir, btd){
- var object = (typeof objOrDir == "string"? document.getElementById(objOrId) : objOrDir);
- if (!object){
- return;
- }
- if (typeof btd == "undefined"){
- btd = this.baseTextDirection;
- }
- if (btd == "auto"){
- btd = this.resolveStrBtd(object.value);
- }
- object.dir = btd;
- };
- //The function checks if the character is an Arabic character or not
- //@c: character to be tested.
- BidiUtils.prototype._isArabicChar = function(c){
- if (c >= 0x0600 && c <= 0x0669 ||
- c >= 0x06fa && c <= 0x07ff ||
- c >= 0xfb50 && c <= 0xfdff ||
- c >= 0xfe70 && c <= 0xfefc) {
- return true;
- }
- else{
- return false;
- }
- };
- //The function checks if the character is a Hebrew character or not
- //@c: character to be tested.
- BidiUtils.prototype._isHebrewChar = function(c){
- if (c >= 0x05d0 && c <= 0x05ff)
- return true;
- else
- return false;
- };
- BidiUtils.prototype._isLTRChar = function(c){
- if (c >= 0x0061 && c <= 0x007A ||
- c >= 0x0041 && c <= 0x005A ||
- c == 0x200E)
- return true;
- else
- return false;
- };
- // This function checks whether character been passed as parameter is Bidi character
- BidiUtils.prototype._isBidiChar = function(c){
- return (this._isArabicChar(c)||this._isHebrewChar(c));
- };
- // This function checks whether character been passed as parameter is Latin character
- BidiUtils.prototype._isLatinChar = function(c){
- if((c > 64 && c < 91)||(c > 96 && c < 123))
- return true;
- else
- return false;
- };
- // This function checks whether character been passed as parameter is digit
- BidiUtils.prototype._isDigit = function(c){
- if((c >= 48 && c <= 57)||(c >= 0x0660 && c <= 0x0669))
- return true;
- else
- return false;
- };
- // This function checks whether character found in str (first paramter) at position pos (second parameter)
- // and backwards [but not before position previousPos (third parameter)] is Bidi character.
- BidiUtils.prototype._isCharBeforeBiDiChar = function(str, pos, previousPos) {
- while (pos > 0){
- if(pos == previousPos){
- return false;
- }
- if(this._isBidiChar(str.charCodeAt(pos-1))){
- return true;
- }
- else if(this._isLatinChar(str.charCodeAt(pos-1))){
- return false;
- }
- pos--;
- }
- return false;
- };
- // This is auxiliary function called from keyup event callback.
- // @object: field where the typing takes place
- // @event: keydown event object
- BidiUtils.prototype._handleKey = function(object,event){
- if (!event) {
- event = window.event;
- }
- var code = event.keyCode;
- if (!code){
- code = event.which;
- }
- if ((code == this._K_HOME) || (code == this._K_END) || (code == this._K_SHIFT) ||
- (code == this._K_ENTER) || (code == this._K_INSERT) || (code == this._K_ESC)) {
- return;
- }
- else if ((code == this._K_UP) || (code == this._K_DOWN) ||
- (code == this._K_PAGEDOWN) || (code == this._K_PAGEUP)) {
- this._adjustCaret(object,event,null);
- return;
- }
- var str1 = object.value;
- var cursorStart, cursorEnd,cursorStart2,cursorEnd2;
- var selection = this._getCaretPos(object,event);
- var selection2;
- if (selection) {
- cursorStart = selection[0];
- cursorEnd = selection[1];
- }
- if(code == this._K_LEFT){
- if (this._checkMarkers(str1.charAt(cursorStart - 1)) && cursorStart == cursorEnd){
- this._setSelectedRange(object, cursorStart - 1, cursorEnd - 1);
- }
- return;
- }
- else if(code == this._K_RIGHT){
- if (this._checkMarkers(str1.charAt(cursorStart - 1)) && cursorStart == cursorEnd){
- cursorStart = (this.isIE) ? (cursorStart + 1) : cursorStart;
- this._setSelectedRange(object, cursorStart, cursorStart);
- }
- return;
- }
- var useArabicRulesForMultiEmail=this._useArabicRulesForMultiEmail(object, object.value);
- if (useArabicRulesForMultiEmail) {
- var markersCount = this._markersCount(str1, cursorStart);
- str2 = this.removeUCCFromStr(str1) ;
- this._setSelectedRange(object, cursorStart - markersCount, cursorEnd - markersCount);
- }
- else {
- str2 = this.removeUCCFromStr(str1);
- }
- if(useArabicRulesForMultiEmail) {
- str2=this._handle_ArabicEmail(str2,object);
- var selection2 = this._getCaretPos(object,event);
- if (selection2) {
- cursorStart2 = selection2[0];
- cursorEnd2 = selection2[1];
- }
- } else {
- str2 = this.sttInjectUCCIntoStr(str2,object.stttype);
- }
- if(str1 != str2){
- object.value = str2;
- if (code != this._K_DELETE && code != this._K_BACK){
- if(useArabicRulesForMultiEmail) {
- if (!this._checkUCC(object.value.charAt(cursorEnd))){
- this._setSelectedRange(object, cursorStart2+1 , cursorEnd2+1 );
- }
- }
- else {
- if (!this._checkMarkers(object.value.charAt(cursorEnd))){
- cursorStart += 1;
- cursorEnd += 1;
- }
- this._setSelectedRange(object, cursorStart, cursorEnd);
- }
- }
- else {
- if(useArabicRulesForMultiEmail) {
- this._setSelectedRange(object,cursorStart2,cursorEnd2);
- }
- else {
- this._setSelectedRange(object,cursorStart,cursorEnd);
- }
- }
- }
- };
- // This is auxiliary function called from keydown event callback.
- // Prevents Bidi markers from being erased on 'delete' and 'backspace' operations
- // @object: field where the typing takes place
- // @event: keydown event object
- BidiUtils.prototype._processBackspaceDelete = function(object,event){
- if (!event) {
- event = window.event;
- }
- var code = event.keyCode;
- if (!code){
- code = event.which;
- }
- if(code != this._K_DELETE && code != this._K_BACK) {
- return;
- }
- var cursorStart, cursorEnd;
- var selection = this._getCaretPos(object,event);
- if (selection) {
- cursorStart = selection[0];
- cursorEnd = selection[1];
- var str1,str2;
- if(cursorStart == cursorEnd) {
- if(this._useArabicRulesForMultiEmail(object, object.value)) {
-
- if ((code == this._K_DELETE) &&
- (this._checkUCC(object.value.charAt(cursorEnd))) &&
- (cursorEnd < object.value.length - 1)) {
-
-
- object.value = object.value.substring(0, cursorEnd) + object.value.substring(cursorEnd + 1);
- this._setSelectedRange(object, cursorEnd, cursorEnd);
-
- }
- else if ((code == this._K_BACK) && (this._checkUCC(object.value.charAt(cursorEnd - 1)))) {
- object.value = object.value.substring(0, cursorEnd - 1) + object.value.substring(cursorEnd);
- this._setSelectedRange(object, cursorEnd - 1, cursorEnd - 1);
- }
- }
- else {
- if ((code == this._K_DELETE) &&
- (this._checkMarkers(object.value.charAt(cursorEnd))) && (cursorEnd < object.value.length - 1)) {
- object.value = object.value.substring(0, cursorEnd) + object.value.substring(cursorEnd + 1);
- this._setSelectedRange(object, cursorEnd, cursorEnd);
- }
- else if ((code == this._K_BACK) && (this._checkMarkers(object.value.charAt(cursorEnd - 1)))) {
- object.value = object.value.substring(0, cursorEnd - 1) + object.value.substring(cursorEnd);
- this._setSelectedRange(object, cursorEnd - 1, cursorEnd - 1);
- }
- }
- }
- }
- };
- // This is auxiliary function called from different event callbacks.
- // Ensures that caret placement doesn't lead to erasing Bidi marker.
- // @object: field where the operation takes place
- // @event: event object
- // @caretPosition: current caret position
- BidiUtils.prototype._adjustCaret = function(object,event,caretPosition){
- if(caretPosition || (event.button != 2)){
- var selection = (caretPosition) ? caretPosition : this._getCaretPos(object,event);
- if (selection){
- if (selection[0] == selection[1]) {
- if(this._checkMarkers(object.value.charAt(selection[1] - 1))) {
- selection[1] += 1;
- selection[0] = null;
- }
- if(caretPosition || !selection[0]) {
- this._setSelectedRange(object, selection[1], selection[1]);
- }
- }
- }
- }
- };
- // This is auxiliary function called from 'copy' event callback
- // in order to ensure correct STT processing
- // @object: field where the operation takes place
- // @event: event object
- BidiUtils.prototype._processCopy = function(object,event){
- var text = "";
- try{
- if (this.isIE) {
- var w = object.document.parentWindow;
- event = w.event;
- var range = object.document.selection.createRange();
- text = range.text;
- }
- else {
- text = object.value.substring(object.selectionStart,object.selectionEnd);
- }
- var textToClipboard = this.removeUCCFromStr(text);
- if (window.clipboardData) {
- window.clipboardData.setData("Text", textToClipboard);
- if (this.isIE || event.returnValue){
- event.returnValue = false;
- }
- else if(event.preventDefault){
- event.preventDefault();
- }
- }
- }catch(ex){console.log("Exception in copy");}
- };
- // This is auxiliary function called from 'paste' event callback
- // in order to ensure correct STT processing
- // @object: field where the operation takes place
- // @event: event object
- BidiUtils.prototype._processPaste = function(object, event){
- if(this.isIE) {
- try {
- var w = object.document.parentWindow;
- event = w.event;
- this.caretPos = this._getCaretPos(object,event);
- var range = document.selection.createRange();
- var sClipboardData = window.clipboardData.getData("Text");
- range.text = sClipboardData;
- this.caretPos[0] = this.caretPos[1] = this.caretPos[0] +
- this.sttInjectUCCIntoStr(sClipboardData,object.stttype).length;
- this.removeUCCFromObj(object);
- this.sttInjectUCCIntoObj(object);
- var thisObj = this;
- setTimeout(function() {
- thisObj._adjustCaret(object,event,thisObj.caretPos);
- }, 100);
- event.returnValue = false;
- }catch(ex){console.log("Exception in paste");}
- }
- };
- // This is auxiliary function called from 'cut' event callback
- // in order to ensure correct STT processing
- // @object: field where the operation takes place
- // @event: event object
- BidiUtils.prototype._processCut = function(object,event){
- this._processCopy(object,event);
- this.caretPos = this._getCaretPos(object,event);
- if(this.isIE) {
- document.selection.clear();
- }
- else{
- object.value = object.value.substring(0,object.selectionStart) + object.value.substring(object.selectionEnd);
- }
- this.caretPos[0] = this.caretPos[1] = Math.min(this.caretPos[0],this.caretPos[1]);
- this.removeUCCFromObj(object);
- this.sttInjectUCCIntoObj(object);
- this._adjustCaret(object,event,this.caretPos);
- };
- // This is auxiliary function called from different event callbacks
- // Returns current caret position
- // @object: field where the typing takes place
- // @event: event object
- BidiUtils.prototype._getCaretPos = function(object,event){
- if (!this.isIE)
- return new Array(object.selectionStart, object.selectionEnd);
- else {
- var range = document.selection.createRange().duplicate();
- var rangeLength = range.text.length;
- range.moveStart('character', -object.value.length);
- return new Array(range.text.length - rangeLength, range.text.length);
- }
- };
- // This is auxiliary function called from different event callbacks
- // Sets the selection (caret position) at selectionStart-selectionEnd
- BidiUtils.prototype._setSelectedRange = function(object,selectionStart,selectionEnd){
- if(this.isIE) {
- var range = object.createTextRange();
- if (range) {
- if (object.type == "textarea"){
- range.moveToElementText(object);
- }
- else{
- range.expand('textedit');
- }
- range.collapse();
- range.moveEnd('character', selectionEnd);
- range.moveStart('character', selectionStart);
- range.select();
- }
- }
- else {
- object.selectionStart=selectionStart;
- object.selectionEnd=selectionEnd;
- }
- };
- // This function checks whether character been passed as parameter is LRM/RLM
- BidiUtils.prototype._checkMarkers = function(ch) {
- return (ch == this.LRM || ch == this.RLM);
- };
- //The function checks if the character at position @pos is a Unicode Control Character
- //@str: String to be tested.
- //@pos: position of character to be checked.
- BidiUtils.prototype._checkUCC = function(str,pos) {
- if (pos >= str.length){
- return false;
- }
- if(pos < 0) {
- return false;
- }
- var c = str.charAt(pos);
- if (this._isUCChar(c)) {
- return true;
- }
- return false;
- };
- //The function checks if the character is a Unicode Control Character
- // @c: character to be tested.
- BidiUtils.prototype._isUCChar = function(c) {
- if (c == this.LRM || c == this.RLM || c == this.LRE || c == this.RLE || c == this.PDF || c == this.ZWNJ){
- return true;
- }
- return false;
- };
- // The function removes bidi markers (UCC) from the string,
- // containing structured text.
- // @str: structured text, containing UCC
- BidiUtils.prototype.removeUCCFromStr = function(str){
- if (!str) {
- return str;
- }
- return str.replace(/\u200E|\u200F|\u200F|\u202A|\u202B|\u200C|\u202C/g,"")
- };
- //The function removes bidi markers (UCC) from the value
- //of the object, containing structured text.
- // @object: object, containing structured text with UCC
- BidiUtils.prototype.removeUCCFromObj = function(object) {
- if (object && object.value){
- object.value = this.removeUCCFromStr(object.value);
- }
- };
- // The function injects UCC into given string in accordance with the
- // given type of structured text.
- // @str: structured text without UCC
- // @sttType: type of the structure
- BidiUtils.prototype.sttInjectUCCIntoStr = function(str, sttType){
- var useArabicRulesForMultiEmail = false;
- if (sttType == this.multiemail) {
- if(this._isArabicText(str)) {
- useArabicRulesForMultiEmail = true;
- }
- }
- if (sttType == "multiemail" && useArabicRulesForMultiEmail) {
- return this._handle_ArabicEmail_Static(str);
- }
- else if(sttType == 'crumb') {
- return this._processBreadCrumb(str);
- }
- else {
- var txt = str.replace(/\\/g,"\\\\");
- txt = txt.replace(/'/g,"\\'");
- var buf = str;
- var sPoints = this["_parse_" + sttType](txt);
- if (typeof sPoints == "undefined"){
- console.log("Parser for STT '" + sttType + "' isn't correct");
- return str;
- }
- var shift = 0;
- var n, preStr, postStr;
- for (var i = 0; i< sPoints.length; i++) {
- n = sPoints[i];
- if(n != null){
- preStr = buf.substring(0, n + shift);
- postStr = buf.substring(n + shift, buf.length);
- buf = preStr + this.LRM + postStr;
- shift++;
- }
- }
- return buf;
- }
- };
- // The function injects UCC into value of the given object in accordance
- // with its type of structured text.
- // @object: object, containig structured text without UCC
- BidiUtils.prototype.sttInjectUCCIntoObj = function(object){
- if (!object.stttype){
- if (object.attributes["stttype"]){
- object.stttype = object.attributes["stttype"].nodeValue;
- }
- else{
- return;
- }
- }
- object.value = this.sttInjectUCCIntoStr(object.value, object.stttype);
- };
- // This is auxiliary function called from _processBreadCrumb
- // Inserts Bidi marks in proper places of bread crumb segment
- BidiUtils.prototype._processSegment = function(sText) {
- var sDir = this.baseTextDirection;
- if(sDir == 'auto') {
- sDir = (this.resolveStrBtd(sText) ? 'rtl' : 'ltr');
- }
- var directionMark = this.BACKREF;
- directionMark += (sDir == 'rtl') ? this.RLE : this.LRE;
- sText = sText.replace(/(^\s{0,})/,directionMark);
- return sText.replace(/(\s{0,}$)/,this.BACKREF_PDF);
- };
- /**
- * Inserts unicode Bidi directional marks before (LRE/RLE) and after (PDF) every
- * subsegment and fixes the delimiter positions by strong directional mark LRM
- *
- * @param {string} sText, containing complex expression to be processed
- * @return {string} processed input string
- */
- BidiUtils.prototype._processBreadCrumb = function(sText) {
- var sBuff = "";
- var strongSeparator = (this.guiOrientation == 'ltr') ? this.LRM : this.RLM;
- var splitArray = sText.split(':');
- if(splitArray.length > 1) {
- sText = splitArray[1];
- sBuff = splitArray[0] + ':' + strongSeparator;
- }
- var splitArray = sText.split('>');
- for (var i = 0; i < splitArray.length; i++) {
- splitArray[i] = this._processSegment(splitArray[i]);
- }
- sBuff += splitArray.join('>' + strongSeparator);
- return sBuff;
- };
- /**
- * Parses string containing complex expression.
- *
- * @param {string} str, input string to be parsed
- * @param {string} delimiters,set of delimiters dedining the type of complex expression
- * @return {Array} array containing points in input string where UCC marks should be inserted
- */
- BidiUtils.prototype._parse_complex_string = function(str, delimiters){
- var sPoints = new Array();
- var previous = -1;
- for (var i = 0; i < str.length; i++){
- if ((delimiters.indexOf(str.charAt(i)) >= 0) && this._isCharBeforeBiDiChar(str,i,previous)){
- previous = i;
- sPoints.push(i);
- }
- }
- return sPoints;
- };
- /**
- * Parses string containing filepath complex expression.
- *
- * @param {string} str, input string to be parsed
- */
- BidiUtils.prototype._parse_filepath = function(str){
- var delimiters = "/\\.";
- return this._parse_complex_string(str,delimiters);
- };
- /**
- * Parses string containing url complex expression.
- *
- * @param {string} str, input string to be parsed
- */
- BidiUtils.prototype._parse_url = function(str){
- var delimiters = "/.?:&=;";
- return this._parse_complex_string(str,delimiters);
- };
- /**
- * Parses string containing multiemail complex expression.
- *
- * @param {string} str, input string to be parsed
- */
- BidiUtils.prototype._parse_multiemail = function(str){
- var delimiters = "<>@.,;";
- return this._parse_complex_string(str,delimiters);
- };
- /**
- * Parses string containing email complex expression.
- *
- * @param {string} str, input string to be parsed
- */
- BidiUtils.prototype._parse_email = function(str){
- var delimiters = "<>@.,;";
- var sPoints = new Array();
- var previous = -1, j;
- for (var i = 0; i < str.length; i++){
- if (str.charAt(i) == '\"') {
- if (this._isCharBeforeBiDiChar(str,i,previous)){
- previous = i;
- sPoints.push(i);
- }
- i++;
- j = str.indexOf('\"', i);
- if(j >= i){
- i = j;
- }
- else{
- continue;
- }
- if (this._isCharBeforeBiDiChar(str,i,previous)){
- previous = i;
- sPoints.push(i);
- }
- }
- if ((delimiters.indexOf(str.charAt(i)) >= 0) && this._isCharBeforeBiDiChar(str,i,previous)){
- previous = i;
- sPoints.push(i);
- }
- }
- return sPoints;
- };
- //The function counts the Unicode Control Characters before character at position @len
- //@str: String to be tested.
- //@len: number of characters to count the markers in them.
- BidiUtils.prototype._markersCount = function(str, len){
- var chr;
- var markersCount = 0;
- var i;
- if (str.length < 1)
- return 0;
- for( i = 0; i < len - 1; i++) {
- chr = str.charAt(i);
- if (this._isUCChar(chr))
- markersCount += 1;
- }
- return markersCount;
- };
- //The function inserts Unicode Control characters into string containing
- //multiple arabic emails and modify cursor position to keep the text well
- //formated during editing
- //@sttString: String containing Email to be handled.
- //@object: Object holding cursor info to be handled.
- BidiUtils.prototype._handle_ArabicEmail = function(sttString, object){
- var resultStr = "";
- var chr;
- var lastSeparatorIndex = -1, lastDelimiterIndex = -1;
- var isLastRTL = false, isLastLTR = false;
- var currentPosition = -1, newPosition = -1;
- var markersCount = 0;
- var i, j;
- var selectionStart;
- var mailDelimiters = "@.<>";
- var mailSeparators = ",;";
- var mailSign = "@";
- var prevEmailDir = 0;
- var cEmbeding, cMarker, cEmailDir = 0;
- var mailSignAvailable = false;
- var isAdded = false;
- var selection = this._getCaretPos(object, null);
- if (selection) {
- var selectionStart = selection[0];
- var selEnd = selection[1];
- }
- currentPosition = selectionStart;
- newPosition = selectionStart;
- markersCount = this._markersCount(sttString, currentPosition);
- sttString = this.removeUCCFromStr(sttString);
- newPosition = newPosition - markersCount;
- if (sttString.length > 0 && mailDelimiters.length > 0) {
- cMarker = this.LRM;
- cEmbeding = this.LRE;
- cEmailDir = this.LTR_DIR;
- resultStr = cEmbeding + resultStr;
- for (i = 0; i < sttString.length; i++) {
- chrCode = sttString.charCodeAt(i);
- chr = sttString.charAt(i);
- if (mailDelimiters.indexOf(chr) != -1) {
- if (mailSign.indexOf(chr) != -1) {
- mailSignAvailable = true;
- }
- if ((cEmailDir == this.LTR_DIR && isLastRTL) || (cEmailDir == this.RTL_DIR && isLastLTR)) {
- lastDelimiterIndex = resultStr.length;
- }
- }
- else if (mailSeparators.indexOf(chr) != -1) {
- mailSignAvailable = false;
- lastSeparatorIndex = i;
- resultStr = resultStr + this.PDF;
- lastDelimiterIndex = resultStr.length;
- }
- else if (this._isDigit(chrCode)) {
- if (lastDelimiterIndex != -1) {
- resultStr = resultStr.substring(0, lastDelimiterIndex) + cMarker + resultStr.substring(lastDelimiterIndex);
- lastDelimiterIndex = -1;
- isLastRTL = false;
- isLastLTR = false;
- }
- }
- else if (this._isBidiChar(chrCode) || this._isLTRChar(chrCode)) {
- if (mailSignAvailable) {
- var nextSeparatorIndex = this._nextSeparator(sttString, i);
- var mailSegment = sttString.substring(lastSeparatorIndex + 1, nextSeparatorIndex + 1);
- var cEmailDir = this._getArabicEmailDirection(mailSegment);
- if ( cEmailDir == this.RTL_DIR ) {
- cMarker = this.RLM;
- cEmbeding = this.RLE;
- }
- else {
- cMarker = this.LRM;
- cEmbeding = this.LRE;
- }
- if (prevEmailDir != cEmailDir && cEmailDir != 0) {
- var lastMailSeparator = this._lastMailSeparator(resultStr, resultStr.length);
- var tmpStr = this.removeUCCFromStr(sttString.substring(lastSeparatorIndex + 1, i + 1));
- var mailSTT = this._handle_ArabicSingleEmail(tmpStr, cEmailDir);
- if (lastMailSeparator > 0)
- resultStr = resultStr.substring(0, lastMailSeparator + 1) + mailSTT.substring(0, mailSTT.length - 1);
- else
- resultStr = mailSTT.substring(0, mailSTT.length - 1);
- isAdded = true;
- }
- prevEmailDir = cEmailDir;
- }
- if (this._isBidiChar(chrCode)) {
- if ((cEmailDir == this.LTR_DIR) && lastDelimiterIndex != -1) {
- resultStr = resultStr.substring(0, lastDelimiterIndex) + this.LRM + resultStr.substring(lastDelimiterIndex);
- lastDelimiterIndex = -1;
- }
- isLastRTL = true;
- isLastLTR = false;
- }
- else {
- if ((cEmailDir == this.RTL_DIR) && lastDelimiterIndex != -1) {
- resultStr = resultStr.substring(0, lastDelimiterIndex) + this.RLM + resultStr.substring(lastDelimiterIndex);
- lastDelimiterIndex = -1;
- }
- isLastLTR = true;
- isLastRTL = false;
- }
- }
- if (isAdded) {
- isAdded = false;
- } else {
- resultStr = resultStr + chr;
- }
- if (mailSeparators.indexOf(chr) != -1) {
- resultStr = resultStr + cEmbeding;
- }
- }
- resultStr = resultStr + this.PDF;
- }
- var newPosition=0;
- var j = currentPosition;
- while(newPosition < j && newPosition < resultStr.length) {
- if (this._isUCChar(resultStr.charAt(newPosition))) {
- j++;
- }
- newPosition++;
- }
- object.value=resultStr;
- this._setSelectedRange(object, newPosition, newPosition);
- return resultStr;
- };
- //The function inserts markers into single Arabic email
- //@sttString: String containing email.
- //@dir: base text direction of the email.
- BidiUtils.prototype._handle_ArabicSingleEmail = function(sttString, dir){
- var resultStr = "";
- var chr;
- var lastDelimiterIndex = -1;
- var isLastRTL = false, isLastLTR = false;
- var cEmbeding, cMarker;
- var i, j;
- var mailDelimiters = "@.<>";
- var cEmailDir = 0;
- cEmailDir = dir;
- if ( cEmailDir == this.RTL_DIR ) {
- cMarker = this.RLM;
- cEmbeding = this.RLE;
- }
- else {
- cMarker = this.LRM;
- cEmbeding = this.LRE;
- }
- if (sttString.length > 0 && mailDelimiters.length > 0) {
- for (i = 0; i < sttString.length; i++) {
- chrCode = sttString.charCodeAt(i);
- chr = sttString.charAt(i);
- if (mailDelimiters.indexOf(chr) != -1) {
- if ((cEmailDir == this.LTR_DIR && isLastRTL) || (cEmailDir == this.RTL_DIR && isLastLTR)) {
- lastDelimiterIndex = resultStr.length;
- }
- }
- else if (this._isDigit(chrCode)) {
- if (lastDelimiterIndex != -1) {
- resultStr = resultStr.substring(0, lastDelimiterIndex) + cMarker + resultStr.substring(lastDelimiterIndex);
- lastDelimiterIndex = -1;
- isLastRTL = false;
- isLastLTR = false;
- }
- }
- else if (this._isBidiChar(chrCode) || this._isLTRChar(chrCode)) {
- if (this._isBidiChar(chrCode)) {
- if ((cEmailDir == this.LTR_DIR) && lastDelimiterIndex != -1) {
- resultStr = resultStr.substring(0, lastDelimiterIndex) + this.LRM + resultStr.substring(lastDelimiterIndex);
- lastDelimiterIndex = -1;
- }
- isLastRTL = true;
- isLastLTR = false;
- }
- else {
- if ((cEmailDir == this.RTL_DIR) && lastDelimiterIndex != -1) {
- resultStr = resultStr.substring(0, lastDelimiterIndex) + this.RLM + resultStr.substring(lastDelimiterIndex);
- lastDelimiterIndex = -1;
- }
- isLastLTR = true;
- isLastRTL = false;
- }
- }
- resultStr = resultStr + chr;
- }
- resultStr = cEmbeding + resultStr + this.PDF;
- }
- return resultStr;
- };
- //The function inserts markers into static emails containing Arabic characters
- //@str: String containing email addresses.
- BidiUtils.prototype._handle_ArabicEmail_Static = function(str) {
- if (str != null && str.length > 0) {
- var cPosition = 0;
- var result = "";
- var separators=";,";
- var lastCharIsSeparator=false;
- while (cPosition < str.length) {
- var nextSeparatorIndex = this._nextSeparator(str, cPosition);
- var mail = str.substring(cPosition, nextSeparatorIndex);
- var dir = this._getArabicEmailDirection(mail);
- if (nextSeparatorIndex < str.length-1) {
- result = result + this._handle_ArabicSingleEmail(mail, dir) + str.charAt(nextSeparatorIndex) ;
- }
- else {
- if(separators.indexOf(str.charAt(nextSeparatorIndex))>-1) {
- lastCharIsSeparator=true;
- }
- else {
- lastCharIsSeparator=false;
- }
- if(lastCharIsSeparator) {
- result = result + this._handle_ArabicSingleEmail(mail, dir)+ str.charAt(nextSeparatorIndex) ;
- }
- else {
- mail=mail+str.charAt(nextSeparatorIndex);
- result = result + this._handle_ArabicSingleEmail(mail, dir) ;
- }
- }
- cPosition = nextSeparatorIndex + 1;
- }
- return result;
- }
- return str;
- };
- //The function determines the position of the last email separator in the string
- //@str: String to be tested.
- //@pos: current position (to start searching from the character after it)
- BidiUtils.prototype._lastMailSeparator = function(str, start){
- var lastComma = str.lastIndexOf(',', start);
- var lastSemiColon = str.lastIndexOf(';', start);
- return Math.max(lastComma, lastSemiColon, 0);
- };
- //The function determines the position of the next email separator in the string, starting from the current position
- //@str: String to be tested.
- //@pos: current position (to start searching from the character after it)
- BidiUtils.prototype._nextSeparator = function(str,start){
- var nextComma=str.indexOf(',',start);
- var len = str.length;
- var nextSemiColon=str.indexOf(';',start);
- if(nextComma<0) {
- nextComma=len-1;
- }
- if(nextSemiColon<0) {
- nextSemiColon=len-1;
- }
- return Math.min(nextComma,nextSemiColon);
- };
- //The function checks if the string should be considered Arabic or not
- //The string is considered Arabic if the first Bidi character found was Arabic
- //@str: string to be tested.
- BidiUtils.prototype._isArabicText = function(str){
- if(!str) {
- return false;
- }
- var len=str.length;
- if(len<1) return false;
- for(var i=0;i<len;i++) {
- //If an Arabic Char is found first, the text is considered Arabic
- if(this._isArabicChar(str.charCodeAt(i))) {
- return true;
- }
- else {
- if(this._isHebrewChar(str.charCodeAt(i))) {
- return false;
- }
- }
- }
- return false;
- };
- //The function checks if the String contains Bidi characters or not
- //@str: String to be tested.
- BidiUtils.prototype._isBidiText = function(str){
- if(str==null) return false;
- var len=str.length;
- if(len<1) return false;
- for(var i=0;i<len;i++) {
- //If an Arabic Char is found first, the text is considered Hebrew
- if(this._isArabicChar(str.charCodeAt(i))||this._isHebrewChar(str.charCodeAt(i))) {
- return true;
- }
- }
- return false;
- };
- //The function checks if the string should be considered Hebrew or not
- //The string is considered Hebrew if the first Bidi character found was Hebrew
- //@str: string to be tested.
- BidiUtils.prototype._isHebrewText = function(str){
- if(!str) {
- return false;
- }
- var len=str.length;
- if(len<1) return false;
- for(var i=0;i<len;i++) {
- //If a Hebrew Char is found first, the text is considered Hebrew
- if(this._isHebrewChar(str.charCodeAt(i))) {
- return true;
- }
- else {
- if(this._isArabicChar(str.charCodeAt(i))) {
- return false;
- }
- }
- }
- return false;
- };
- //The function checks if the string may be an email address or not
- //@str: String to be tested.
- BidiUtils.prototype._isEmailAddress = function(str){
- if(str==null) return false;
- if(str.length<1) return false;
- if(str.indexOf('@')<0) {
- return false;
- }
- return true;
- };
- //The function returns the domain of the email contained in the string @str
- //@str: String representing the full email address .
- BidiUtils.prototype._getEmailDomain = function(str){
- var segments=str.split('@');
- return segments[1];
- };
- //The function decides if the text direction of email is LTR or RTL
- //If the domain contains Bidi characters, the text direction is RTL
- //else the text direction is LTR
- //@str: String representing email address to be tested.
- BidiUtils.prototype._getArabicEmailDirection = function(str){
- var domain = this._getEmailDomain(str);
- if(this._isBidiText(domain)) {
- return this.RTL_DIR;
- }
- else {
- return this.LTR_DIR;
- }
- };
- //The function determines if Arabic rules should be used for emails as STT
- //Should return true if the stttype of the object is multiemail and the text is considered Arabic
- //if the passed String is used and if it is equal to null the value in the object is used instead
- //@object: Object whose value will be processed.
- //@str: The string to be tested if it is Arabic or not
- BidiUtils.prototype._useArabicRulesForMultiEmail = function(object,str){
- if(!object) {
- return false;
- }
- if(!str) {
- str=object.value;
- if(!str) {
- return false;
- }
- }
- if((object.stttype==this.multiemail) || (object.stttype=="email")) {
- if(this._isArabicText(str)) {
- return true;
- }
- }
- return false;
- };
|