source: Dev/trunk/src/client/dijit/InlineEditBox.js @ 536

Last change on this file since 536 was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

File size: 21.7 KB
Line 
1define([
2        "require",
3        "dojo/_base/array", // array.forEach
4        "dojo/aspect",
5        "dojo/_base/declare", // declare
6        "dojo/dom-attr", // domAttr.set domAttr.get
7        "dojo/dom-class", // domClass.add domClass.remove domClass.toggle
8        "dojo/dom-construct", // domConstruct.create domConstruct.destroy
9        "dojo/dom-style", // domStyle.getComputedStyle domStyle.set domStyle.get
10        "dojo/i18n", // i18n.getLocalization
11        "dojo/_base/kernel", // kernel.deprecated
12        "dojo/keys", // keys.ENTER keys.ESCAPE
13        "dojo/_base/lang", // lang.getObject
14        "dojo/on",
15        "dojo/sniff", // has("ie")
16        "dojo/when",
17        "./a11yclick",
18        "./focus",
19        "./_Widget",
20        "./_TemplatedMixin",
21        "./_WidgetsInTemplateMixin",
22        "./_Container",
23        "./form/Button",
24        "./form/_TextBoxMixin",
25        "./form/TextBox",
26        "dojo/text!./templates/InlineEditBox.html",
27        "dojo/i18n!./nls/common"
28], function(require, array, aspect, declare, domAttr, domClass, domConstruct, domStyle, i18n, kernel, keys, lang, on, has, when, a11yclick, fm, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin, _Container, Button, _TextBoxMixin, TextBox, template){
29
30        // module:
31        //              dijit/InlineEditBox
32
33        var InlineEditor = declare("dijit._InlineEditor", [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin], {
34                // summary:
35                //              Internal widget used by InlineEditBox, displayed when in editing mode
36                //              to display the editor and maybe save/cancel buttons.  Calling code should
37                //              connect to save/cancel methods to detect when editing is finished
38                //
39                //              Has mainly the same parameters as InlineEditBox, plus these values:
40                //
41                // style: Object
42                //              Set of CSS attributes of display node, to replicate in editor
43                //
44                // value: String
45                //              Value as an HTML string or plain text string, depending on renderAsHTML flag
46
47                templateString: template,
48
49                contextRequire: require,
50
51                postMixInProperties: function(){
52                        this.inherited(arguments);
53                        this.messages = i18n.getLocalization("dijit", "common", this.lang);
54                        array.forEach(["buttonSave", "buttonCancel"], function(prop){
55                                if(!this[prop]){
56                                        this[prop] = this.messages[prop];
57                                }
58                        }, this);
59                },
60
61                buildRendering: function(){
62                        this.inherited(arguments);
63
64                        // Create edit widget in place in the template
65                        // TODO: remove getObject() for 2.0
66                        var Cls = typeof this.editor == "string" ? (lang.getObject(this.editor) || require(this.editor)) : this.editor;
67
68                        // Copy the style from the source
69                        // Don't copy ALL properties though, just the necessary/applicable ones.
70                        // wrapperStyle/destStyle code is to workaround IE bug where getComputedStyle().fontSize
71                        // is a relative value like 200%, rather than an absolute value like 24px, and
72                        // the 200% can refer *either* to a setting on the node or it's ancestor (see #11175)
73                        var srcStyle = this.sourceStyle,
74                                editStyle = "line-height:" + srcStyle.lineHeight + ";",
75                                destStyle = domStyle.getComputedStyle(this.domNode);
76                        array.forEach(["Weight", "Family", "Size", "Style"], function(prop){
77                                var textStyle = srcStyle["font" + prop],
78                                        wrapperStyle = destStyle["font" + prop];
79                                if(wrapperStyle != textStyle){
80                                        editStyle += "font-" + prop + ":" + srcStyle["font" + prop] + ";";
81                                }
82                        }, this);
83                        array.forEach(["marginTop", "marginBottom", "marginLeft", "marginRight", "position", "left", "top", "right", "bottom", "float", "clear", "display"], function(prop){
84                                this.domNode.style[prop] = srcStyle[prop];
85                        }, this);
86                        var width = this.inlineEditBox.width;
87                        if(width == "100%"){
88                                // block mode
89                                editStyle += "width:100%;";
90                                this.domNode.style.display = "block";
91                        }else{
92                                // inline-block mode
93                                editStyle += "width:" + (width + (Number(width) == width ? "px" : "")) + ";";
94                        }
95                        var editorParams = lang.delegate(this.inlineEditBox.editorParams, {
96                                style: editStyle,
97                                dir: this.dir,
98                                lang: this.lang,
99                                textDir: this.textDir
100                        });
101                        // set the value in onLoadDeferred instead so the widget has time to finish initializing
102                        //editorParams[("displayedValue" in Cls.prototype || "_setDisplayedValueAttr" in Cls.prototype) ? "displayedValue" : "value"] = this.value;
103                        this.editWidget = new Cls(editorParams, this.editorPlaceholder);
104
105                        if(this.inlineEditBox.autoSave){
106                                // Remove the save/cancel buttons since saving is done by simply tabbing away or
107                                // selecting a value from the drop down list
108                                domConstruct.destroy(this.buttonContainer);
109                        }
110                },
111
112                postCreate: function(){
113                        this.inherited(arguments);
114
115                        var ew = this.editWidget;
116
117                        if(this.inlineEditBox.autoSave){
118                                this.own(
119                                        // Selecting a value from a drop down list causes an onChange event and then we save
120                                        aspect.after(ew, "onChange", lang.hitch(this, "_onChange"), true),
121
122                                        // ESC and TAB should cancel and save.
123                                        on(ew, "keydown", lang.hitch(this, "_onKeyDown"))
124                                );
125                        }else{
126                                // If possible, enable/disable save button based on whether the user has changed the value
127                                if("intermediateChanges" in ew){
128                                        ew.set("intermediateChanges", true);
129                                        this.own(aspect.after(ew, "onChange", lang.hitch(this, "_onIntermediateChange"), true));
130                                        this.saveButton.set("disabled", true);
131                                }
132                        }
133                },
134
135                startup: function(){
136                        this.editWidget.startup();
137                        this.inherited(arguments);
138                },
139
140                _onIntermediateChange: function(/*===== val =====*/){
141                        // summary:
142                        //              Called for editor widgets that support the intermediateChanges=true flag as a way
143                        //              to detect when to enable/disabled the save button
144                        this.saveButton.set("disabled", (this.getValue() == this._resetValue) || !this.enableSave());
145                },
146
147                destroy: function(){
148                        this.editWidget.destroy(true); // let the parent wrapper widget clean up the DOM
149                        this.inherited(arguments);
150                },
151
152                getValue: function(){
153                        // summary:
154                        //              Return the [display] value of the edit widget
155                        var ew = this.editWidget;
156                        return String(ew.get(("displayedValue" in ew || "_getDisplayedValueAttr" in ew) ? "displayedValue" : "value"));
157                },
158
159                _onKeyDown: function(e){
160                        // summary:
161                        //              Handler for keydown in the edit box in autoSave mode.
162                        // description:
163                        //              For autoSave widgets, if Esc/Enter, call cancel/save.
164                        // tags:
165                        //              private
166
167                        if(this.inlineEditBox.autoSave && this.inlineEditBox.editing){
168                                if(e.altKey || e.ctrlKey){
169                                        return;
170                                }
171                                // If Enter/Esc pressed, treat as save/cancel.
172                                if(e.keyCode == keys.ESCAPE){
173                                        e.stopPropagation();
174                                        e.preventDefault();
175                                        this.cancel(true); // sets editing=false which short-circuits _onBlur processing
176                                }else if(e.keyCode == keys.ENTER && e.target.tagName == "INPUT"){
177                                        e.stopPropagation();
178                                        e.preventDefault();
179                                        this._onChange(); // fire _onBlur and then save
180                                }
181
182                                // _onBlur will handle TAB automatically by allowing
183                                // the TAB to change focus before we mess with the DOM: #6227
184                                // Expounding by request:
185                                //      The current focus is on the edit widget input field.
186                                //      save() will hide and destroy this widget.
187                                //      We want the focus to jump from the currently hidden
188                                //      displayNode, but since it's hidden, it's impossible to
189                                //      unhide it, focus it, and then have the browser focus
190                                //      away from it to the next focusable element since each
191                                //      of these events is asynchronous and the focus-to-next-element
192                                //      is already queued.
193                                //      So we allow the browser time to unqueue the move-focus event
194                                //      before we do all the hide/show stuff.
195                        }
196                },
197
198                _onBlur: function(){
199                        // summary:
200                        //              Called when focus moves outside the editor
201                        // tags:
202                        //              private
203
204                        this.inherited(arguments);
205                        if(this.inlineEditBox.autoSave && this.inlineEditBox.editing){
206                                if(this.getValue() == this._resetValue){
207                                        this.cancel(false);
208                                }else if(this.enableSave()){
209                                        this.save(false);
210                                }
211                        }
212                },
213
214                _onChange: function(){
215                        // summary:
216                        //              Called when the underlying widget fires an onChange event,
217                        //              such as when the user selects a value from the drop down list of a ComboBox,
218                        //              which means that the user has finished entering the value and we should save.
219                        // tags:
220                        //              private
221
222                        if(this.inlineEditBox.autoSave && this.inlineEditBox.editing && this.enableSave()){
223                                fm.focus(this.inlineEditBox.displayNode); // fires _onBlur which will save the formatted value
224                        }
225                },
226
227                enableSave: function(){
228                        // summary:
229                        //              User overridable function returning a Boolean to indicate
230                        //              if the Save button should be enabled or not - usually due to invalid conditions
231                        // tags:
232                        //              extension
233                        return this.editWidget.isValid ? this.editWidget.isValid() : true;
234                },
235
236                focus: function(){
237                        // summary:
238                        //              Focus the edit widget.
239                        // tags:
240                        //              protected
241
242                        this.editWidget.focus();
243
244                        if(this.editWidget.focusNode){
245                                // IE can take 30ms to report the focus event, but focus manager needs to know before a 0ms timeout.
246                                fm._onFocusNode(this.editWidget.focusNode);
247
248                                if(this.editWidget.focusNode.tagName == "INPUT"){
249                                        this.defer(function(){
250                                                _TextBoxMixin.selectInputText(this.editWidget.focusNode);
251                                        });
252                                }
253                        }
254                }
255        });
256
257
258        var InlineEditBox = declare("dijit.InlineEditBox" + (has("dojo-bidi") ? "_NoBidi" : ""), _Widget, {
259                // summary:
260                //              An element with in-line edit capabilities
261                //
262                // description:
263                //              Behavior for an existing node (`<p>`, `<div>`, `<span>`, etc.) so that
264                //              when you click it, an editor shows up in place of the original
265                //              text.  Optionally, Save and Cancel button are displayed below the edit widget.
266                //              When Save is clicked, the text is pulled from the edit
267                //              widget and redisplayed and the edit widget is again hidden.
268                //              By default a plain Textarea widget is used as the editor (or for
269                //              inline values a TextBox), but you can specify an editor such as
270                //              dijit.Editor (for editing HTML) or a Slider (for adjusting a number).
271                //              An edit widget must support the following API to be used:
272                //
273                //              - displayedValue or value as initialization parameter,
274                //                      and available through set('displayedValue') / set('value')
275                //              - void focus()
276                //              - DOM-node focusNode = node containing editable text
277
278                // editing: [readonly] Boolean
279                //              Is the node currently in edit mode?
280                editing: false,
281
282                // autoSave: Boolean
283                //              Changing the value automatically saves it; don't have to push save button
284                //              (and save button isn't even displayed)
285                autoSave: true,
286
287                // buttonSave: String
288                //              Save button label
289                buttonSave: "",
290
291                // buttonCancel: String
292                //              Cancel button label
293                buttonCancel: "",
294
295                // renderAsHtml: Boolean
296                //              Set this to true if the specified Editor's value should be interpreted as HTML
297                //              rather than plain text (ex: `dijit.Editor`)
298                renderAsHtml: false,
299
300                // editor: String|Function
301                //              MID (ex: "dijit/form/TextBox") or constructor for editor widget
302                editor: TextBox,
303
304                // editorWrapper: String|Function
305                //              Class name (or reference to the Class) for widget that wraps the editor widget, displaying save/cancel
306                //              buttons.
307                editorWrapper: InlineEditor,
308
309                // editorParams: Object
310                //              Set of parameters for editor, like {required: true}
311                editorParams: {},
312
313                // disabled: Boolean
314                //              If true, clicking the InlineEditBox to edit it will have no effect.
315                disabled: false,
316
317                onChange: function(/*===== value =====*/){
318                        // summary:
319                        //              Set this handler to be notified of changes to value.
320                        // tags:
321                        //              callback
322                },
323
324                onCancel: function(){
325                        // summary:
326                        //              Set this handler to be notified when editing is cancelled.
327                        // tags:
328                        //              callback
329                },
330
331                // width: String
332                //              Width of editor.  By default it's width=100% (ie, block mode).
333                width: "100%",
334
335                // value: String
336                //              The display value of the widget in read-only mode
337                value: "",
338
339                // noValueIndicator: [const] String
340                //              The text that gets displayed when there is no value (so that the user has a place to click to edit)
341                noValueIndicator: has("ie") <= 6 ? // font-family needed on IE6 but it messes up IE8
342                        "<span style='font-family: wingdings; text-decoration: underline;'>&#160;&#160;&#160;&#160;&#x270d;&#160;&#160;&#160;&#160;</span>" :
343                        "<span style='text-decoration: underline;'>&#160;&#160;&#160;&#160;&#x270d;&#160;&#160;&#160;&#160;</span>", // &#160; == &nbsp;
344
345                constructor: function(/*===== params, srcNodeRef =====*/){
346                        // summary:
347                        //              Create the widget.
348                        // params: Object|null
349                        //              Hash of initialization parameters for widget, including scalar values (like title, duration etc.)
350                        //              and functions, typically callbacks like onClick.
351                        //              The hash can contain any of the widget's properties, excluding read-only properties.
352                        // srcNodeRef: DOMNode|String?
353                        //              If a srcNodeRef (DOM node) is specified:
354                        //
355                        //              - use srcNodeRef.innerHTML as my value
356                        //              - replace srcNodeRef with my generated DOM tree
357
358                        this.editorParams = {};
359                },
360
361                postMixInProperties: function(){
362                        this.inherited(arguments);
363
364                        // save pointer to original source node, since Widget nulls-out srcNodeRef
365                        this.displayNode = this.srcNodeRef;
366
367                        // connect handlers to the display node
368                        this.own(
369                                on(this.displayNode, a11yclick, lang.hitch(this, "_onClick")),
370                                on(this.displayNode, "mouseover, focus", lang.hitch(this, "_onMouseOver")),
371                                on(this.displayNode, "mouseout, blur", lang.hitch(this, "_onMouseOut"))
372                        );
373
374                        this.displayNode.setAttribute("role", "button");
375                        if(!this.displayNode.getAttribute("tabIndex")){
376                                this.displayNode.setAttribute("tabIndex", 0);
377                        }
378
379                        if(!this.value && !("value" in this.params)){ // "" is a good value if specified directly so check params){
380                                this.value = lang.trim(this.renderAsHtml ? this.displayNode.innerHTML :
381                                        (this.displayNode.innerText || this.displayNode.textContent || ""));
382                        }
383                        if(!this.value){
384                                this.displayNode.innerHTML = this.noValueIndicator;
385                        }
386
387                        domClass.add(this.displayNode, 'dijitInlineEditBoxDisplayMode');
388                },
389
390                setDisabled: function(/*Boolean*/ disabled){
391                        // summary:
392                        //              Deprecated.   Use set('disabled', ...) instead.
393                        // tags:
394                        //              deprecated
395                        kernel.deprecated("dijit.InlineEditBox.setDisabled() is deprecated.  Use set('disabled', bool) instead.", "", "2.0");
396                        this.set('disabled', disabled);
397                },
398
399                _setDisabledAttr: function(/*Boolean*/ disabled){
400                        // summary:
401                        //              Hook to make set("disabled", ...) work.
402                        //              Set disabled state of widget.
403                        this.domNode.setAttribute("aria-disabled", disabled ? "true" : "false");
404                        if(disabled){
405                                this.displayNode.removeAttribute("tabIndex");
406                        }else{
407                                this.displayNode.setAttribute("tabIndex", 0);
408                        }
409                        domClass.toggle(this.displayNode, "dijitInlineEditBoxDisplayModeDisabled", disabled);
410                        this._set("disabled", disabled);
411                },
412
413                _onMouseOver: function(){
414                        // summary:
415                        //              Handler for onmouseover and onfocus event.
416                        // tags:
417                        //              private
418                        if(!this.disabled){
419                                domClass.add(this.displayNode, "dijitInlineEditBoxDisplayModeHover");
420                        }
421                },
422
423                _onMouseOut: function(){
424                        // summary:
425                        //              Handler for onmouseout and onblur event.
426                        // tags:
427                        //              private
428                        domClass.remove(this.displayNode, "dijitInlineEditBoxDisplayModeHover");
429                },
430
431                _onClick: function(/*Event*/ e){
432                        // summary:
433                        //              Handler for onclick event.
434                        // tags:
435                        //              private
436                        if(this.disabled){
437                                return;
438                        }
439                        if(e){
440                                e.stopPropagation();
441                                e.preventDefault();
442                        }
443                        this._onMouseOut();
444
445                        // Since FF gets upset if you move a node while in an event handler for that node...
446                        this.defer("edit");
447                },
448
449                edit: function(){
450                        // summary:
451                        //              Display the editor widget in place of the original (read only) markup.
452                        // tags:
453                        //              private
454
455                        if(this.disabled || this.editing){
456                                return;
457                        }
458                        this._set('editing', true);
459
460                        // save some display node values that can be restored later
461                        this._savedTabIndex = domAttr.get(this.displayNode, "tabIndex") || "0";
462
463                        if(!this.wrapperWidget){
464                                // Placeholder for edit widget
465                                // Put place holder (and eventually editWidget) before the display node so that it's positioned correctly
466                                // when Calendar dropdown appears, which happens automatically on focus.
467                                var placeholder = domConstruct.create("span", null, this.domNode, "before");
468
469                                // Create the editor wrapper (the thing that holds the editor widget and the save/cancel buttons)
470                                var Ewc = typeof this.editorWrapper == "string" ? lang.getObject(this.editorWrapper) : this.editorWrapper;
471                                this.wrapperWidget = new Ewc({
472                                        value: this.value,
473                                        buttonSave: this.buttonSave,
474                                        buttonCancel: this.buttonCancel,
475                                        dir: this.dir,
476                                        lang: this.lang,
477                                        tabIndex: this._savedTabIndex,
478                                        editor: this.editor,
479                                        inlineEditBox: this,
480                                        sourceStyle: domStyle.getComputedStyle(this.displayNode),
481                                        save: lang.hitch(this, "save"),
482                                        cancel: lang.hitch(this, "cancel"),
483                                        textDir: this.textDir
484                                }, placeholder);
485                                if(!this.wrapperWidget._started){
486                                        this.wrapperWidget.startup();
487                                }
488                                if(!this._started){
489                                        this.startup();
490                                }
491                        }
492                        var ww = this.wrapperWidget;
493
494                        // to avoid screen jitter, we first create the editor with position: absolute, visibility: hidden,
495                        // and then when it's finished rendering, we switch from display mode to editor
496                        // position: absolute releases screen space allocated to the display node
497                        // opacity:0 is the same as visibility: hidden but is still focusable
498                        // visibility: hidden removes focus outline
499
500                        domClass.add(this.displayNode, "dijitOffScreen");
501                        domClass.remove(ww.domNode, "dijitOffScreen");
502                        domStyle.set(ww.domNode, { visibility: "visible" });
503                        domAttr.set(this.displayNode, "tabIndex", "-1"); // needed by WebKit for TAB from editor to skip displayNode
504
505                        // After edit widget has finished initializing (in particular need to wait for dijit.Editor),
506                        // or immediately if there is no onLoadDeferred Deferred,
507                        // replace the display widget with edit widget, leaving them both displayed for a brief time so that
508                        // focus can be shifted without incident.
509                        var ew = ww.editWidget;
510                        var self = this;
511                        when(ew.onLoadDeferred, lang.hitch(ww, function(){
512                                // set value again in case the edit widget's value is just now valid
513                                ew.set(("displayedValue" in ew || "_setDisplayedValueAttr" in ew) ? "displayedValue" : "value", self.value);
514                                this.defer(function(){ // defer needed so that the change of focus doesn't happen on mousedown which also sets focus
515                                        // the saveButton should start out disabled in most cases but the above set could have fired onChange
516                                        ww.saveButton.set("disabled", "intermediateChanges" in ew);
517                                        this.focus(); // both nodes are showing, so we can switch focus safely
518                                        this._resetValue = this.getValue();
519                                });
520                        }));
521                },
522
523                _onBlur: function(){
524                        // summary:
525                        //              Called when focus moves outside the InlineEditBox.
526                        //              Performs garbage collection.
527                        // tags:
528                        //              private
529
530                        this.inherited(arguments);
531                        if(!this.editing){
532                                /* causes IE focus problems, see TooltipDialog_a11y.html...
533                                 this.defer(function(){
534                                 if(this.wrapperWidget){
535                                 this.wrapperWidget.destroy();
536                                 delete this.wrapperWidget;
537                                 }
538                                 });
539                                 */
540                        }
541                },
542
543                destroy: function(){
544                        if(this.wrapperWidget && !this.wrapperWidget._destroyed){
545                                this.wrapperWidget.destroy();
546                                delete this.wrapperWidget;
547                        }
548                        this.inherited(arguments);
549                },
550
551                _showText: function(/*Boolean*/ focus){
552                        // summary:
553                        //              Revert to display mode, and optionally focus on display node
554                        // tags:
555                        //              private
556
557                        var ww = this.wrapperWidget;
558                        domStyle.set(ww.domNode, { visibility: "hidden" }); // hide the editor from mouse/keyboard events
559                        domClass.add(ww.domNode, "dijitOffScreen");
560                        domClass.remove(this.displayNode, "dijitOffScreen");
561                        domAttr.set(this.displayNode, "tabIndex", this._savedTabIndex);
562                        if(focus){
563                                fm.focus(this.displayNode);
564                        }
565                },
566
567                save: function(/*Boolean*/ focus){
568                        // summary:
569                        //              Save the contents of the editor and revert to display mode.
570                        // focus: Boolean
571                        //              Focus on the display mode text
572                        // tags:
573                        //              private
574
575                        if(this.disabled || !this.editing){
576                                return;
577                        }
578                        this._set('editing', false);
579
580                        var ww = this.wrapperWidget;
581                        var value = ww.getValue();
582                        this.set('value', value); // display changed, formatted value
583
584                        this._showText(focus); // set focus as needed
585                },
586
587                setValue: function(/*String*/ val){
588                        // summary:
589                        //              Deprecated.   Use set('value', ...) instead.
590                        // tags:
591                        //              deprecated
592                        kernel.deprecated("dijit.InlineEditBox.setValue() is deprecated.  Use set('value', ...) instead.", "", "2.0");
593                        return this.set("value", val);
594                },
595
596                _setValueAttr: function(/*String*/ val){
597                        // summary:
598                        //              Hook to make set("value", ...) work.
599                        //              Inserts specified HTML value into this node, or an "input needed" character if node is blank.
600
601                        val = lang.trim(val);
602                        var renderVal = this.renderAsHtml ? val : val.replace(/&/gm, "&amp;").replace(/</gm, "&lt;").replace(/>/gm, "&gt;").replace(/"/gm, "&quot;").replace(/\n/g, "<br>");
603                        this.displayNode.innerHTML = renderVal || this.noValueIndicator;
604                        this._set("value", val);
605
606                        if(this._started){
607                                // tell the world that we have changed
608                                this.defer(function(){
609                                        this.onChange(val);
610                                }); // defer prevents browser freeze for long-running event handlers
611                        }
612                },
613
614                getValue: function(){
615                        // summary:
616                        //              Deprecated.   Use get('value') instead.
617                        // tags:
618                        //              deprecated
619                        kernel.deprecated("dijit.InlineEditBox.getValue() is deprecated.  Use get('value') instead.", "", "2.0");
620                        return this.get("value");
621                },
622
623                cancel: function(/*Boolean*/ focus){
624                        // summary:
625                        //              Revert to display mode, discarding any changes made in the editor
626                        // tags:
627                        //              private
628
629                        if(this.disabled || !this.editing){
630                                return;
631                        }
632                        this._set('editing', false);
633
634                        // tell the world that we have no changes
635                        this.defer("onCancel"); // defer prevents browser freeze for long-running event handlers
636
637                        this._showText(focus);
638                }
639        });
640
641        if(has("dojo-bidi")){
642                InlineEditBox = declare("dijit.InlineEditBox", InlineEditBox, {
643                        _setValueAttr: function(){
644                                this.inherited(arguments);
645                                this.applyTextDir(this.displayNode);
646                        }
647                });
648        }
649
650        InlineEditBox._InlineEditor = InlineEditor;     // for monkey patching
651
652        return InlineEditBox;
653});
Note: See TracBrowser for help on using the repository browser.