source: Dev/trunk/src/client/dojox/editor/plugins/AutoSave.js

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

Added Dojo 1.9.3 release.

File size: 12.7 KB
Line 
1define([
2        "dojo",
3        "dijit",        // _scopeName
4        "dojox",
5        "dijit/_base/manager",  // getUniqueId()
6        "dijit/_base/popup",
7        "dijit/_Widget",
8        "dijit/_TemplatedMixin",
9        "dijit/_WidgetsInTemplateMixin",
10        "dijit/Dialog",
11        "dijit/MenuItem",
12        "dijit/Menu",
13        "dijit/form/Button",
14        "dijit/form/ComboButton",
15        "dijit/form/ComboBox",
16        "dijit/form/_TextBoxMixin",     // selectInputText()
17        "dijit/form/TextBox",
18        "dijit/TooltipDialog",
19        "dijit/_editor/_Plugin",
20        "dojo/_base/connect",
21        "dojo/_base/declare",
22        "dojo/date/locale",
23        "dojo/i18n",
24        "dojo/string",
25        "dojox/editor/plugins/Save",
26        "dojo/i18n!dojox/editor/plugins/nls/AutoSave"
27], function(dojo, dijit, dojox, manager, popup, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin,
28        Dialog, MenuItem, Menu, Button, ComboButton, ComboBox, _TextBoxMixin, TextBox, TooltipDialog, _Plugin,
29        connect, declare, locale, i18n, string, Save) {
30
31dojo.experimental("dojox.editor.plugins.AutoSave");
32
33var AutoSaveSettingDialog = dojo.declare("dojox.editor.plugins._AutoSaveSettingDialog", [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin], {
34       
35        // dialogTitle [public] String
36        //              The tile of the Auto-Save setting dialog
37        dialogTitle: "",
38       
39        // dialogDescription [public] String
40        //              The description of the Auto-Save setting dialog
41        dialogDescription: "",
42       
43        // paramName [public] String
44        //              The name of the parameter (Auto-Save Interval)
45        paramName: "",
46       
47        // paramLabel [public] String
48        //              Minute
49        paramLabel: "",
50       
51        // btnOk [public] String
52        //              The label of the OK button
53        btnOk: "",
54       
55        // btnCancel [public] String
56        //              The label of the Cancel button
57        btnCancel: "",
58       
59        widgetsInTemplate: true,
60       
61        templateString:
62                "<span id='${dialogId}' class='dijit dijitReset dijitInline' tabindex='-1'>" +
63                        "<div dojoType='dijit.Dialog' title='${dialogTitle}' dojoAttachPoint='dialog' " +
64                                "class='dijitEditorAutoSaveSettingDialog'>" +
65                                "<div tabindex='-1'>${dialogDescription}</div>" +
66                                "<div tabindex='-1' class='dijitEditorAutoSaveSettingInputArea'>${paramName}</div>" +
67                                "<div class='dijitEditorAutoSaveSettingInputArea' tabindex='-1'>" +
68                                        "<input class='textBox' dojoType='dijit.form.TextBox' id='${textBoxId}' required='false' intermediateChanges='true' " +
69                                                "selectOnClick='true' required='true' dojoAttachPoint='intBox' " +
70                                                "dojoAttachEvent='onKeyDown: _onKeyDown, onChange: _onChange'/>" +
71                                        "<label class='dijitLeft dijitInline boxLabel' " +
72                                                "for='${textBoxId}' tabindex='-1'>${paramLabel}</label>" +
73                                "</div>" +
74                                "<div class='dijitEditorAutoSaveSettingButtonArea' tabindex='-1'>" +
75                                        "<button dojoType='dijit.form.Button' dojoAttachEvent='onClick: onOk'>${btnOk}</button>" +
76                                        "<button dojoType='dijit.form.Button' dojoAttachEvent='onClick: onCancel'>${btnCancel}</button>" +
77                                "</div>" +
78                        "</div>" +
79                "</span>",
80       
81        postMixInProperties: function(){
82                this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
83                this.dialogId = this.id + "_dialog";
84                this.textBoxId = this.id + "_textBox";
85        },
86       
87        show: function(){
88                // summary:
89                //              Display the setting dialog. If the internal interval value is ""
90                //              set it to zero
91                // tags:
92                //              public
93                if(this._value == ""){
94                        this._value = 0;
95                        this.intBox.set("value", 0);
96                }else{
97                        this.intBox.set("value", this._value);
98                }
99                this.dialog.show();
100                dijit.selectInputText(this.intBox.focusNode);
101        },
102       
103        hide: function(){
104                // summary:
105                //              Hide the setting dialog.
106                // tags:
107                //              public
108                this.dialog.hide();
109        },
110       
111        onOk: function(){
112                // summary:
113                //              Handle the OK event and close the dialog.
114                // tags:
115                //              public
116                this.dialog.hide();
117        },
118       
119        onCancel: function(){
120                // summary:
121                //              Handle the Cancel event and close the dialog.
122                // tags:
123                //              public
124                this.dialog.hide();
125        },
126       
127        _onKeyDown: function(evt){
128                // summary:
129                //              Handle the keydown event
130                // tags:
131                //              private
132                if(evt.keyCode == dojo.keys.ENTER){
133                        this.onOk();
134                }
135        },
136       
137        _onChange: function(/*String*/ val){
138                // summary:
139                //              Check if the value is between 1 - 999.
140                // tags:
141                //              public
142                if(this._isValidValue(val)){
143                        this._value = val;
144                }else{
145                        this.intBox.set("value", this._value);
146                }
147        },
148       
149        _setValueAttr: function(/*String*/ val){
150                // summary:
151                //              Set the value attribute if it is acceptable
152                // val:
153                //              The interval value
154                // tags:
155                //              private
156                if(this._isValidValue(val)){
157                        this._value = val;
158                }
159        },
160       
161        _getValueAttr: function(){
162                // summary:
163                //              Get the interval value
164                // tags:
165                //              protected
166                return this._value;
167        },
168       
169        _isValidValue: function(/*String*/ val){
170                // summary:
171                //              Check if this value between 1- 999
172                // tags:
173                //              private
174                var regExp = /^\d{0,3}$/,
175                        _v = String(val);
176                return Boolean(_v.match ? _v.match(regExp) : "");
177        }
178});
179
180var AutoSave = dojo.declare("dojox.editor.plugins.AutoSave", Save, {
181        // summary:
182        //              This plugin provides the auto save capability to the editor. The
183        //              plugin saves the content of the editor in interval. When
184        //              the save action is performed, the document in the editor frame
185        //              will be posted to the URL provided, or none, if none provided.
186       
187        // url: [public] String
188        //              The URL to POST the content back to.  Used by the save function.
189        url: "",
190
191        // logResults: [public] Boolean
192        //              Boolean flag to indicate that the default action for save and
193        //              error handlers is to just log to console.  Default is true.
194        logResults: true,
195       
196        // interval: [public] Number
197        //              The interval to perform the save action.
198        interval: 0,
199       
200        // _iconClassPrefix: [private] String
201        //              This prefix of the CSS class
202        _iconClassPrefix: "dijitEditorIconAutoSave",
203       
204        // _MIN: [private const] Number
205        //              Default 1 minute
206        _MIN: 60000,
207       
208        _setIntervalAttr: function(val){
209                // summary:
210                //              Set the interval value.
211                //              Delay the boundary check to _isValidValue of the dialog class
212                // val:
213                //              The interval value.
214                // tags:
215                //              private
216                this.interval = val;
217        },
218       
219        _getIntervalAttr: function(){
220                // summary:
221                //              Get the interval value
222                // tags:
223                //              private
224                return this._interval;
225        },
226       
227        setEditor: function(editor){
228                // summary:
229                //              Over-ride for the setting of the editor. No toggle button for
230                //              this plugin. And start to save the content of the editor in
231                //              interval
232                // editor: Object
233                //              The editor to configure for this plugin to use.
234                this.editor = editor;
235                this._strings = dojo.i18n.getLocalization("dojox.editor.plugins", "AutoSave");
236                this._initButton();
237               
238                this._saveSettingDialog = new AutoSaveSettingDialog({
239                        "dialogTitle": this._strings["saveSettingdialogTitle"],
240                        "dialogDescription": this._strings["saveSettingdialogDescription"],
241                        "paramName": this._strings["saveSettingdialogParamName"],
242                        "paramLabel": this._strings["saveSettingdialogParamLabel"],
243                        "btnOk": this._strings["saveSettingdialogButtonOk"],
244                        "btnCancel": this._strings["saveSettingdialogButtonCancel"]
245                });
246                this.connect(this._saveSettingDialog, "onOk", "_onDialogOk");
247               
248                var pd = (this._promDialog = new dijit.TooltipDialog());
249                pd.startup();
250                pd.set("content", "");
251        },
252       
253        _initButton: function(){
254                var menu = new dijit.Menu({
255                                style: "display: none"
256                        }),
257                        menuItemSave = new dijit.MenuItem({
258                                iconClass: this._iconClassPrefix + "Default " + this._iconClassPrefix,
259                                label: this._strings["saveLabel"]
260                        }),
261                        menuItemAutoSave = (this._menuItemAutoSave = new dijit.MenuItem({
262                                iconClass: this._iconClassPrefix + "Setting " + this._iconClassPrefix,
263                                label: this._strings["saveSettingLabelOn"]
264                        }));
265                       
266                menu.addChild(menuItemSave);
267                menu.addChild(menuItemAutoSave);
268                this.button = new dijit.form.ComboButton({
269                        label: this._strings["saveLabel"],
270                        iconClass: this._iconClassPrefix + "Default " + this._iconClassPrefix,
271                        showLabel: false,
272                        dropDown: menu
273                });
274               
275                this.connect(this.button, "onClick", "_save");
276                this.connect(menuItemSave, "onClick", "_save");
277                this._menuItemAutoSaveClickHandler = dojo.connect(menuItemAutoSave, "onClick", this, "_showAutSaveSettingDialog");
278        },
279       
280        _showAutSaveSettingDialog: function(){
281                // summary:
282                //              Show the setting dialog
283                // tags:
284                //              private
285                var dialog = this._saveSettingDialog;
286                dialog.set("value", this.interval);
287                dialog.show();
288        },
289       
290        _onDialogOk: function(){
291                // summary:
292                //              If the interval is set (larger than 0), enable auto-save.
293                // tags:
294                //              private
295                var interval = (this.interval = this._saveSettingDialog.get("value") * this._MIN);
296                if(interval > 0){
297                        this._setSaveInterval(interval);
298                        // Change the menu "Set Auto-Save Interval..." to "Turn off Auto-Save"
299                        // Connect it to another handler that terminates the auto-save.
300                        dojo.disconnect(this._menuItemAutoSaveClickHandler);
301                        this._menuItemAutoSave.set("label", this._strings["saveSettingLabelOff"]);
302                        this._menuItemAutoSaveClickHandler = dojo.connect(this._menuItemAutoSave, "onClick", this, "_onStopClick");
303                        // Change the icon of the main button to auto-save style
304                        this.button.set("iconClass", this._iconClassPrefix + "Setting " + this._iconClassPrefix);
305                }
306        },
307       
308        _onStopClick: function(){
309                // summary:
310                //              Stop auto-save
311                // tags:
312                //              private
313                this._clearSaveInterval();
314                // Change the menu "Turn off Auto-Save" to "Set Auto-Save Interval...".
315                // Connect it to another handler that show the setting dialog.
316                dojo.disconnect(this._menuItemAutoSaveClickHandler);
317                this._menuItemAutoSave.set("label", this._strings["saveSettingLabelOn"]);
318                this._menuItemAutoSaveClickHandler = dojo.connect(this._menuItemAutoSave, "onClick", this, "_showAutSaveSettingDialog");
319                // Change the icon of the main button
320                this.button.set("iconClass", this._iconClassPrefix + "Default " + this._iconClassPrefix);
321        },
322       
323        _setSaveInterval: function(/*Number*/ interval){
324                // summary:
325                //              Function to trigger saving of the editor document
326                // tags:
327                //              private
328                if(interval <= 0){
329                        return;
330                }
331                this._clearSaveInterval();
332                this._intervalHandler = setInterval(dojo.hitch(this,  function(){
333                                                                        if(!this._isWorking && !this.get("disabled")){
334                                                                                // If the plugin is not disabled (ViewSource, etc.)
335                                                                                // and not working. Do saving!
336                                                                                this._isWorking = true;
337                                                                                this._save();
338                                                                        }
339                                                                }), interval);
340        },
341       
342        _clearSaveInterval: function(){
343                if(this._intervalHandler){
344                        clearInterval(this._intervalHandler);
345                        this._intervalHandler = null;
346                }
347        },
348
349        onSuccess: function(resp, ioargs){
350                // summary:
351                //              User over-ridable save success function for editor content.
352                // resp:
353                //              The response from the server, if any, in text format.
354                // tags:
355                //              public
356                this.button.set("disabled", false);
357                // Show the successful message
358                this._promDialog.set("content", dojo.string.substitute(
359                                        this._strings["saveMessageSuccess"], {"0": dojo.date.locale.format(new Date(), {selector: "time"})}));
360                                dijit.popup.open({popup: this._promDialog, around: this.button.domNode});
361                                this._promDialogTimeout = setTimeout(dojo.hitch(this, function(){
362                                        clearTimeout(this._promDialogTimeout);
363                                        this._promDialogTimeout = null;
364                                        dijit.popup.close(this._promDialog);
365                                }), 3000);
366                this._isWorking = false;
367                if(this.logResults){
368                        console.log(resp);
369                }
370        },
371
372        onError: function(error, ioargs){
373                // summary:
374                //              User over-ridable save success function for editor content.
375                // resp:
376                //              The response from the server, if any, in text format.
377                // tags:
378                //              public
379                this.button.set("disabled", false);
380                // Show the failure message
381                this._promDialog.set("content", dojo.string.substitute(
382                                        this._strings["saveMessageFail"], {"0": dojo.date.locale.format(new Date(), {selector: "time"})}));
383                                dijit.popup.open({popup: this._promDialog, around: this.button.domNode});
384                                this._promDialogTimeout = setTimeout(dojo.hitch(this, function(){
385                                        clearTimeout(this._promDialogTimeout);
386                                        this._promDialogTimeout = null;
387                                        dijit.popup.close(this._promDialog);
388                                }), 3000);
389                this._isWorking = false;
390                if(this.logResults){
391                        console.log(error);
392                }
393        },
394       
395        destroy: function(){
396                // summary:
397                //              Cleanup of our plugin.
398                this.inherited(arguments);
399               
400                this._menuItemAutoSave = null;
401               
402                if(this._promDialogTimeout){
403                        clearTimeout(this._promDialogTimeout);
404                        this._promDialogTimeout = null;
405                        dijit.popup.close(this._promDialog);
406                }
407               
408                this._clearSaveInterval();
409               
410                if(this._saveSettingDialog){
411                        this._saveSettingDialog.destroyRecursive();
412                        this._destroyRecursive = null;
413                }
414               
415                if(this._menuItemAutoSaveClickHandler){
416                        dojo.disconnect(this._menuItemAutoSaveClickHandler);
417                        this._menuItemAutoSaveClickHandler = null;
418                }
419        }
420});
421
422// For monkey patching
423AutoSave._AutoSaveSettingDialog = AutoSaveSettingDialog;
424
425// Register this plugin.
426dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
427        if(o.plugin){ return; }
428        var name = o.args.name.toLowerCase();
429        if(name == "autosave"){
430                o.plugin = new AutoSave({
431                        url: ("url" in o.args) ? o.args.url : "",
432                        logResults: ("logResults" in o.args) ? o.args.logResults : true,
433                        interval: ("interval" in o.args) ? o.args.interval : 5
434                });
435        }
436});
437
438return AutoSave;
439
440});
Note: See TracBrowser for help on using the repository browser.