[483] | 1 | define([], function(){ |
---|
| 2 | |
---|
| 3 | // module: |
---|
| 4 | // dijit/_BidiMixin |
---|
| 5 | |
---|
| 6 | // UCC - constants that will be used by bidi support. |
---|
| 7 | var bidi_const = { |
---|
| 8 | LRM : '\u200E', |
---|
| 9 | LRE : '\u202A', |
---|
| 10 | PDF : '\u202C', |
---|
| 11 | RLM : '\u200f', |
---|
| 12 | RLE : '\u202B' |
---|
| 13 | }; |
---|
| 14 | |
---|
| 15 | return { |
---|
| 16 | // summary: |
---|
| 17 | // When has("dojo-bidi") is true, _WidgetBase will mixin this class. It enables support for the textdir |
---|
| 18 | // property to control text direction independently from the GUI direction. |
---|
| 19 | // description: |
---|
| 20 | // There's a special need for displaying BIDI text in rtl direction |
---|
| 21 | // in ltr GUI, sometimes needed auto support. |
---|
| 22 | // In creation of widget, if it's want to activate this class, |
---|
| 23 | // the widget should define the "textDir". |
---|
| 24 | |
---|
| 25 | // textDir: String |
---|
| 26 | // Bi-directional support, the main variable which is responsible for the direction of the text. |
---|
| 27 | // The text direction can be different than the GUI direction by using this parameter in creation |
---|
| 28 | // of a widget. |
---|
| 29 | // |
---|
| 30 | // Allowed values: |
---|
| 31 | // |
---|
| 32 | // 1. "ltr" |
---|
| 33 | // 2. "rtl" |
---|
| 34 | // 3. "auto" - contextual the direction of a text defined by first strong letter. |
---|
| 35 | // |
---|
| 36 | // By default is as the page direction. |
---|
| 37 | textDir: "", |
---|
| 38 | |
---|
| 39 | getTextDir: function(/*String*/ text){ |
---|
| 40 | // summary: |
---|
| 41 | // Gets the right direction of text. |
---|
| 42 | // description: |
---|
| 43 | // If textDir is ltr or rtl returns the value. |
---|
| 44 | // If it's auto, calls to another function that responsible |
---|
| 45 | // for checking the value, and defining the direction. |
---|
| 46 | // tags: |
---|
| 47 | // protected. |
---|
| 48 | return this.textDir == "auto" ? this._checkContextual(text) : this.textDir; |
---|
| 49 | }, |
---|
| 50 | |
---|
| 51 | _checkContextual: function(text){ |
---|
| 52 | // summary: |
---|
| 53 | // Finds the first strong (directional) character, return ltr if isLatin |
---|
| 54 | // or rtl if isBidiChar. |
---|
| 55 | // tags: |
---|
| 56 | // private. |
---|
| 57 | |
---|
| 58 | // look for strong (directional) characters |
---|
| 59 | var fdc = /[A-Za-z\u05d0-\u065f\u066a-\u06ef\u06fa-\u07ff\ufb1d-\ufdff\ufe70-\ufefc]/.exec(text); |
---|
| 60 | // if found return the direction that defined by the character, else return widgets dir as defult. |
---|
| 61 | return fdc ? ( fdc[0] <= 'z' ? "ltr" : "rtl" ) : this.dir ? this.dir : this.isLeftToRight() ? "ltr" : "rtl"; |
---|
| 62 | }, |
---|
| 63 | |
---|
| 64 | applyTextDir: function(/*DOMNode*/ element, /*String?*/ text){ |
---|
| 65 | // summary: |
---|
| 66 | // Set element.dir according to this.textDir, assuming this.textDir has a value. |
---|
| 67 | // element: |
---|
| 68 | // The text element to be set. Should have dir property. |
---|
| 69 | // text: |
---|
| 70 | // If specified, and this.textDir is "auto", for calculating the right transformation |
---|
| 71 | // Otherwise text read from element. |
---|
| 72 | // description: |
---|
| 73 | // If textDir is ltr or rtl returns the value. |
---|
| 74 | // If it's auto, calls to another function that responsible |
---|
| 75 | // for checking the value, and defining the direction. |
---|
| 76 | // tags: |
---|
| 77 | // protected. |
---|
| 78 | |
---|
| 79 | if(this.textDir){ |
---|
| 80 | var textDir = this.textDir; |
---|
| 81 | if(textDir == "auto"){ |
---|
| 82 | // convert "auto" to either "ltr" or "rtl" |
---|
| 83 | if(typeof text === "undefined"){ |
---|
| 84 | // text not specified, get text from element |
---|
| 85 | var tagName = element.tagName.toLowerCase(); |
---|
| 86 | text = (tagName == "input" || tagName == "textarea") ? element.value : |
---|
| 87 | element.innerText || element.textContent || ""; |
---|
| 88 | } |
---|
| 89 | textDir = this._checkContextual(text); |
---|
| 90 | } |
---|
| 91 | |
---|
| 92 | if(element.dir != textDir){ |
---|
| 93 | // set element's dir to match textDir, but not when textDir is null and not when it already matches |
---|
| 94 | element.dir = textDir; |
---|
| 95 | } |
---|
| 96 | } |
---|
| 97 | }, |
---|
| 98 | |
---|
| 99 | enforceTextDirWithUcc: function(option, text){ |
---|
| 100 | // summary: |
---|
| 101 | // Wraps by UCC (Unicode control characters) option's text according to this.textDir |
---|
| 102 | // option: |
---|
| 103 | // The element (`<option>`) we wrapping the text for. |
---|
| 104 | // text: |
---|
| 105 | // The text to be wrapped. |
---|
| 106 | // description: |
---|
| 107 | // There's a dir problem with some HTML elements. For some elements (e.g. `<option>`, `<select>`) |
---|
| 108 | // defining the dir in different direction then the GUI orientation, won't display correctly. |
---|
| 109 | // FF 3.6 will change the alignment of the text in option - this doesn't follow the bidi standards (static text |
---|
| 110 | // should be aligned following GUI direction). IE8 and Opera11.10 completely ignore dir setting for `<option>`. |
---|
| 111 | // Therefore the only solution is to use UCC (Unicode control characters) to display the text in correct orientation. |
---|
| 112 | // This function saves the original text value for later restoration if needed, for example if the textDir will change etc. |
---|
| 113 | if(this.textDir){ |
---|
| 114 | if(option){ |
---|
| 115 | option.originalText = text; |
---|
| 116 | } |
---|
| 117 | var dir = this.textDir == "auto" ? this._checkContextual(text) : this.textDir; |
---|
| 118 | return (dir == "ltr" ? bidi_const.LRE : bidi_const.RLE ) + text + bidi_const.PDF; |
---|
| 119 | } |
---|
| 120 | return text; |
---|
| 121 | }, |
---|
| 122 | |
---|
| 123 | restoreOriginalText: function(origObj){ |
---|
| 124 | // summary: |
---|
| 125 | // Restores the text of origObj, if needed, after enforceTextDirWithUcc, e.g. set("textDir", textDir). |
---|
| 126 | // origObj: |
---|
| 127 | // The element (`<option>`) to restore. |
---|
| 128 | // description: |
---|
| 129 | // Sets the text of origObj to origObj.originalText, which is the original text, without the UCCs. |
---|
| 130 | // The function than removes the originalText from origObj! |
---|
| 131 | if(origObj.originalText){ |
---|
| 132 | origObj.text = origObj.originalText; |
---|
| 133 | delete origObj.originalText; |
---|
| 134 | } |
---|
| 135 | return origObj; |
---|
| 136 | }, |
---|
| 137 | |
---|
| 138 | _setTextDirAttr: function(/*String*/ textDir){ |
---|
| 139 | // summary: |
---|
| 140 | // Setter for textDir. |
---|
| 141 | // description: |
---|
| 142 | // Users shouldn't call this function; they should be calling |
---|
| 143 | // set('textDir', value) |
---|
| 144 | if(!this._created || this.textDir != textDir){ |
---|
| 145 | this._set("textDir", textDir); |
---|
| 146 | var node = null; |
---|
| 147 | if(this.displayNode){ |
---|
| 148 | node = this.displayNode; |
---|
| 149 | this.displayNode.align = this.dir == "rtl" ? "right" : "left"; |
---|
| 150 | }else{ |
---|
| 151 | node = this.textDirNode || this.focusNode || this.textbox; |
---|
| 152 | } |
---|
| 153 | if(node){ |
---|
| 154 | this.applyTextDir(node); |
---|
| 155 | } |
---|
| 156 | } |
---|
| 157 | } |
---|
| 158 | }; |
---|
| 159 | }); |
---|