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 | }); |
---|