Remoto - VFS: vfsClient.js Source File
Remoto - VFS
vfsClient.js
Go to the documentation of this file.
1 
2 define( [
3  'include/loader/loader',
4  'include/modal/modal',
5  'remoto!stdlib:js/include/preferences.js',
6  'remoto!stdlib:js/include/objectRegistry.js',
7  'remoto!stdlib:js/include/utils.js',
8  'remoto!stdlib:js/paneManager/footer.js',
9  'remoto!stdlib:js/paneManager/paneManager.js',
10  'remoto!stdlib:js/paneManager/paneMenu.js',
11  'remoto!stdlib:js/panes/paneFactory.js',
12  'jquery/jquery',
13  ],
15  {
16  'use strict';
17 
18  loader.reset();
19 
20  var config = null;
21 
44  function vfsClient(_config,bootstrap)
45  {
46  config = _config;
47  bootstrap._preferences = preferences;
48 
49  this._authDenied = false;
50 
51  this._footer = new footer(config);
52 
54  paneManager.objectFactory = this.createPane.bind(this);
55  paneManager.objectDestroy = this.destroyPane.bind(this);
56  paneManager.pathAddedCallback = this.subscribe.bind(this);
58  paneManager.pathDeleteCallback = this.postDelete.bind(this);
59  paneManager.pathCreateCallback = this.postCreate.bind(this);
60  paneManager.pathSubmitCallback = this.postUpdate.bind(this);
61  paneManager.saveCallback = this.saveInterface.bind(this);
62  paneFactory.postUpdate = this.postUpdate.bind(this);
63  paneFactory.postCreate = this.postCreate.bind(this);
64  paneFactory.postDelete = this.postDelete.bind(this);
67  objectRegistry.pathAddedCallback = this.subscribe.bind(this);
68  objectRegistry.pathRemovedCallback = this.unsubscribe.bind(this);
69  objectRegistry.pathReadCallback = this.read.bind(this);
70  objectRegistry.pathReadSingleCallback = this.readSingle.bind(this);
71  objectRegistry.pathMetadataCallback = this.metadata.bind(this);
72 
73  this._batches = {
74  "subscribe": { timer:null, data:{} },
75  "unsubscribe": { timer:null, data:{} },
76  "read": { timer:null, data:{} },
77  "delete": { timer:null, data:{} },
78  "metadata": { timer:null, data:{} },
79  "saveLayout": { timer:null, data:null },
80  };
81 
82  this._socket = bootstrap._socket;
83 
84  $(window).bind("lsModalRequest",this.postLSRequest.bind(this)); //ls requests bubble up from the modal window... catch them!
85  this._lsRequests = {};
86 
87  $(window).bind("openApplicationLayout", paneManager.openApplicationLayout.bind(paneManager) ); //requests to open applications also bubble up, and get punted off to the paneManager
88 
89  $(window).bind("openUserPreferences", this.openUserPreferences.bind(this) );
90 
91  $(window).bind("footerhide", (function(e,hide) {
92  if (hide) this._footer.hide();
93  else this._footer.show();
94  }).bind(this));
95 
96  $(window).bind("triggerCurrentPane",this.currentPaneTrigger.bind(this)); //if a pane has a trigger set for when it becomes current, it will trigger this event with some additional data
97 
98  $(window).bind("switchuser",window.switchuser);
99  $(window).bind("logout",window.logout);
100  $(window).bind("reload",window.reload);
101 
102  //console.dir(requirejs.config("remoto"));
103  //requirejs.config("remoto").client = this; //...which will supercede the bootstrap
104  //this._codeRequests = {};
105 
106  preferences.reset(); //so that no preferences linger from another session
107  }
108 
109  vfsClient.prototype = {
110 
119  destroy: function()
120  {
121  if (config)
122  document.title = config.applicationName;
123 
124  config = null;
125  preferences.reset();
126 
127  paneManager.reset();
129 
130  if (this._footer)
131  this._footer.destroy();
132  this._footer = null;
133 
134  if (this._socket)
135  this._socket.destroy();
136  this._socket = null;
137 
138  this._lsRequests = {};
139  //this._codeRequests = {};
140 
141  $(window).unbind(); //NOTE: this may have unintended side effects if other classes bind to window
142 
143  //requirejs.config("remoto").client = null; //remove this VFS client from remoto plugin, which will disable it until a new vfsClient is initialized
144  },
145 
155  message: function(j)
156  {
157  //console.log(j);
158  if (preferences.fetch('trace')===true)
159  {
160  if ( ( preferences.fetch('traceExcludeLogs')!==true) ||
161  ( (j.attributes && ['logs/messages','logs/warnings','logs/errors','logs/critical','logs/log'].indexOf(j.attributes.path) == -1) )
162  )
163  {
164  if (j.attributes && j.attributes.path)
165  console.log("'"+j.attributes.path+"'");
166  //console.log(m);
167  console.log(j);
168  }
169  }
170 
171  var command = j.command;
172  var attrs = j.attributes;
173  //console.log(":: "+attrs.path);
174 
175  switch( command )
176  {
177  case "diff": var p = utils.cleanPath(attrs.path);
178  var d = attrs.diff;
179  // console.log(p);
180  // console.log(t);
181  // console.log(d);
182 
183  //if (!p) { console.trace(m); return; }
184 
185  this.applyDiff( p, d, j.user );
186  break;
187 
188  case "read": var p = utils.cleanPath(attrs.path);
189  var m = attrs.metadata;
190  var d = attrs.data;
191 
192  //console.log("vfsclient read",arguments);
193 
194  //if (!p || p=="undefined") { console.trace(m); return; }
195 
196  this.applyRead( p, d, m );
197  break;
198 
199  case "subscribe": var p = utils.cleanPath(attrs.path);
200  var m = attrs.metadata;
201  var d = attrs.data;
202 
203  //if (!p) { console.trace(j); return; }
204 
205  this.applySubscription( p, d, m );
206  break;
207 
208  case "metadata": var p = utils.cleanPath(attrs.path);
209  var m = attrs.metadata;
210 
211  //if (!p) { console.trace(m); return; }
212 
213  this.applyMetadata( p, m );
214  break;
215 
216  case "requestlock": var p = utils.cleanPath(attrs.path);
217  var d = attrs.data;
218 
219  this.applyRequestLock( p, d );
220  break;
221 
222  case "releaselock": var p = utils.cleanPath(attrs.path);
223  var d = attrs.data;
224 
225  this.applyReleaseLock( p, d );
226  break;
227 
228  case "ls": //this case is for when a file select is open, and we want to feed listings back to a modal.
229  //console.log(attrs);
230  var id = attrs.id;
231  var path = utils.cleanPath(attrs.path);
232  var entries = attrs.data || {};
233  var metadata = attrs.metadata || {};
234 
235  var m = this._lsRequests[id];
236  if (m)
237  {
238  //console.error("GOT LISTING:"+m);
239  delete this._lsRequests[id];
240  if (m.callback)
241  m.callback(path,entries,metadata);
242  // else if ("fetchedDirectory" in m)
243  // m.fetchedDirectory(path, entries, metadata);
244  else
245  { console.error("No callback for LS request on "+path+" ("+id+")");
246  console.log(m);
247  }
248  }
249  else
250  console.error("Unknown LS id: "+id);
251  break;
252 
253  /*
254  case "code": var name = attrs.name;
255  var code = attrs.code;
256  var error = attrs.error;
257  if (name in this._codeRequests)
258  {
259  var c,ca = this._codeRequests[name];
260  while(ca.length)
261  {
262  c = ca.pop();
263  if (error)
264  { c.error(error);
265  modal.alert(error);
266  }
267  else
268  c.success(code);
269  }
270  delete this._codeRequests[name];
271  }
272  else
273  { console.error("Received code without a request: "+name);
274  //console.error(this._codeRequests);
275  modal.alert("Received code without a corresponding request for '"+name+"'");
276  }
277  break;
278  */
279 
280  case "write": //console.log("would do write here...");
281  //console.log(j);
282  //console.log(attrs);
283 
284  var metadata = attrs.metadata || {};
285  var data = attrs.data || {};
286  var type = attrs.type;
287  var path = attrs.path;
288 
289  switch (type)
290  {
291  case "form": var title = metadata.title || "form";
292  var size = metadata.size || null;
293  var form = data.attributes || data;
294  paneManager.openModalForm(path,form,title,size);
295  break;
296 
297  case "reload": console.warn("Server requested a reload...");
298  $(window).trigger("reload");
299  break;
300 
301  default: console.log("unknown write metadata type: "+type);
302  break;
303  }
304 
305  break;
306 
307  //for acknowledging that a create has occurred
308  //case "create": var metadata = attrs.metadata || {};
309  // break;
310 
311  case "requestsuccess": //console.log("request success!",attrs);
312  var c = attrs.command;
313  var p = attrs.path;
314  var d = attrs.data;
315  var m = attrs.metadata;
316 
317  this.applyRequestSuccess( c, p, d, m );
318  break;
319 
320  case "requesterror": //console.log("request error!",attrs);
321  var c = attrs.command;
322  var p = attrs.path;
323  var r = attrs.reason;
324 
325  this.applyRequestError( c, p, r );
326  break;
327 
328  default: console.error("Bad command: "+command);
329  console.log(j);
330  break;
331  }
332 
333  this._footer.statusState = "RECEIVED";
334  },
335 
346  send: function(command,attributes)
347  {
348  var p = { command:command };
349 
350  if (attributes) p.attributes = attributes;
351 
352  //console.trace("SENDING",p);
353 
354  var m = JSON.stringify(p);
355 
356  //if (this._socket)
357  this._socket.send(m);
358  //else
359  // console.trace("send but no socket!",arguments);
360 
361  //if (this._footer)
362  this._footer.statusState = "PENDING";
363  },
364 
374  initializeUI: function(userinfo)
375  {
376  //console.log(userinfo);
377  config.username = userinfo.username;
378  config.realname = userinfo.realname;
379  config.uidnumber = userinfo.uidnumber;
380  config.layoutsPath = utils.cleanPath( userinfo.layoutsPath );
381  config.preferencesBase = utils.cleanPath( userinfo.preferencesBase );
382  config.preferencesPath = utils.cleanPath( userinfo.preferencesPath );
383  config.interfacePath = utils.cleanPath( userinfo.interfacePath );
384  config.settingsPath = utils.cleanPath( userinfo.settingsPath );
385 
386  preferences.set("username", config.username );
387  preferences.set("realname", config.realname );
388  preferences.set("uidnumber", config.uidnumber );
389  preferences.set("preferencesBase", config.preferencesBase );
390  preferences.set("preferencesPath", config.preferencesPath );
391  preferences.set("settingsPath", config.settingsPath );
392 
393  //this._footer.user = config.username;
394  this._footer.user = config.realname;
395  document.title = config.applicationName+" - "+config.realname;
396 
397  if (!objectRegistry.isRegistered(config.preferencesPath,preferences))
398  objectRegistry.registerObject(config.preferencesPath, preferences, true);
399 
400  // objectRegistry.registerObject( config.interfacePath, paneManager );
401 
402  //var p = [ config.interfacePath, config.layoutsPath ];//, config.applicationsPath ];
403  var p = [];
404 
405  //var _paths = p.concat( paneManager.pathList(), objectRegistry.pathList() );
406  var _paths = p.concat( objectRegistry.pathList() );
407  //console.log(_paths);
408 
409  modal.cancelAllModals(); //close any dangling windows, which are probably error messages
410  //preferences.reset(); //already in constructor
412  //menuManager.createMenu( config.menuPath );
413  //menuManager.createMenu( config.layoutsPath, config.layoutsPath, true );
414 
415  paneManager.initialize(config.interfacePath); //initialize menus, subscribe to layout, etc.
416 
417  // var m = menuManager.getMenu("__tabswitcherMenu");
418  // m.addItem("spacer");
419  // m.addSubMenu( "Load Session Layout", config.layoutsPath, null, this.applyLayoutHandler.bind(this) );
420  // m.addSubMenu( "Delete Session Layout", config.layoutsPath, null, this.deleteLayoutHandler.bind(this) );
421  // m.addItem( { label:"Save Layout", callback:this.saveLayoutPrompt.bind(this) } );
422  // m.addItem("spacer");
423  // m.addItem( { label:"Add Horizontal Split", callback:this.splitLayout.bind(this,"horizontal") } );
424  // m.addItem( { label:"Add Vertical Split", callback:this.splitLayout.bind(this,"vertical") } );
425  // m.addItem( { label:"Refine Layout", callback:this.refineLayoutModal.bind(this) } );
426 
427  // m = menuManager.getMenu("__tabsMenu");
428  // m.addItem("spacer");
429  // //m.addSubMenu( "Create Pane", config.menuPath, null, this.createPaneHandler.bind(this) );
430  // m.addItem( { label:"Create Pane", callback:this.createPaneByPathHandler.bind(this) } );
431 
432  this.subscribe(_paths);
433  },
434 
446  applyDiff: function( path, diff, user )
447  {
448  //console.log(arguments);
449 
450  // if (path === config.interfacePath)
451  // paneManager.applyLayout(diff);
452 
453  var d = objectRegistry.applyDiff(path,diff,user);
454 
455  //we create an exception for path="logs" for the case of a user who
456  //is not subscribed to the logger but may have unsubscribed in a widget/modal
457  //this is not as clean as one would like, to be sure.
458  if (!d && path!=="logs")
459  {
460  console.warn("Non-existent diff path: '"+path+"', or an exception was thrown." );
461  console.log(diff);
462  }
463  },
464 
476  applySubscription: function( path, data, metadata )
477  {
478  // if (path === config.interfacePath)
479  // paneManager.applyLayout(data);
480 
482 
483  if (!d)
484  {
485  console.warn("Non-existent subscription path: '"+path+"'");
486  console.log(arguments);
487  }
488  },
489 
501  applyRead: function( path, data, metadata )
502  {
503  var d = objectRegistry.applyRead(path,data,metadata);
504 
505  if (!d) console.warn("Non-existent read path: "+path);
506  },
507 
518  applyMetadata: function( path, metadata )
519  {
521 
522  if (!d) console.warn("Non-existent metadata path: "+path);
523  },
524 
535  applyRequestLock: function( path, data )
536  {
537  var d = objectRegistry.applyRequestLock(path,data);
538 
539  if (!d) console.warn("Non-existent requestlock path: "+path);
540  },
541 
552  applyReleaseLock: function( path, data )
553  {
554  var d = objectRegistry.applyReleaseLock(path,data);
555 
556  if (!d) console.warn("Non-existent releaselock path: "+path);
557  },
558 
559 
572  applyRequestSuccess: function( command, path, data, metadata )
573  {
574  //console.log(arguments);
575  var d = objectRegistry.applyRequestSuccess(command,path,data,metadata);
576 
577  if (!d) console.warn("Non-existent requestsuccess path: "+path);
578  },
579 
580 
592  applyRequestError: function( command, path, reason )
593  {
594  //console.log(arguments);
595  var d = objectRegistry.applyRequestError(command,path,reason);
596 
597  if (command !== "unsubscribe")
598  if (!d) console.warn("No objects with path '"+path+"' to catch request error.",arguments);
599  },
600 
609  saveLayoutPrompt: function()
610  {
611  modal.prompt( "Enter a name for this layout:",
612  "Layout Name",
613  this.saveLayoutHandler.bind(this)
614  );
615  },
616 
626  saveLayoutHandler: function(name)
627  {
628  console.log("SAVE LAYOUT: "+name); //FIXME
629  //console.log(arguments);
630  },
631 
640  refineLayoutModal: function()
641  {
642  modal.alert( "Will refine layout here. Will be able to set percentage vs fixed sizes on splits." );
643  },
644 
654  splitLayout: function(which)
655  {
656  modal.alert( "Will apply layout split here. Will apply split to overall layout." );
657  },
658 
669  applyLayoutHandler: function(menuData,data)
670  {
671  //console.trace(arguments);
672  console.log("APPLY LAYOUT",arguments); //FIXME
673  //return false;
674  },
675 
686  deleteLayoutHandler: function(tab,data)
687  {
688  console.log("DELETE LAYOUT",arguments); //FIXME
689  //console.log(arguments);
690  },
691 
703  //the objectFactory callback
704  createPane: function(layout,callback)
705  {
706  var p = paneFactory(layout,callback);
707 
708  return p;
709  },
710 
720  //the objectDestroy callback
721  destroyPane: function(pane)
722  {
723  //FIXME: should already be unsubscribed by the pane registry.
724  //this.unsubscribe([pane._path]);
725 
726  //FIXME: remove the pane from any menus?
727  },
728 
739  //the callback for menus who wish to create a pane
740  createPaneHandler: function(tab,data)
741  {
742  //console.log(arguments);
743  //console.log("PANE on tab: "+tab._id+" "+data.path);
744  data.name = data.path;
745  paneManager.createPane(data,null,tab);
746  },
747 
756  createPaneByPathHandler: function()
757  { console.log("Disabled createByPath for now.");
758  },
759 
769  postCreate: function(create)
770  {
771  //console.log("Creating node!");
772  //console.log(create);
773 
774  this.send("create", create);
775  },
776 
786  postUpdate: function(update)
787  {
788  //console.log("Post update!");
789  //console.log(arguments);
790 
791  // if(config.preferencesPath in update)
792  // preferences.update( update[config.preferencesPath] );
793 
794  //console.log(update);
795  this.send("submit", update);
796  },
797 
807  postDelete: /*function(del)
808  {
809  this.send("rm",del);
810  },*/
811 
812  function(del)
813  {
814  for (var d in del)
815  {
816  var p = utils.cleanPath( d );
817  if (!this._batches.delete.data[p])
818  this._batches.delete.data[p] = true;
819  }
820 
821  if (!this._batches.delete.timer)
822  { var THIS = this;
823  this._batches.delete.timer = requestAnimationFrame( function() {
824  THIS.send("rm", THIS._batches.delete.data);
825  THIS._batches.delete = { timer:null, data:{} };
826  } );
827  }
828  },
829 
840  postLSRequest: function(event,params)
841  {
842  //console.warn("LS");
843  //console.log(arguments);
844 
845  this._lsRequests[params.id] = { modal:params.modal, callback:params.callback };
846 
847  var p = {};
848  p[params.id] = { path:params.path, metadata:params.metadata };
849 
850  this.send("ls",p);
851  },
852 
853  /*
854  //this is moved to boostrap.js
855  postCodeRequest: function( library, callback, errback )
856  {
857  if (!this._codeRequests[library]) this._codeRequests[library] = [];
858 
859  this._codeRequests[library].push( { success:callback, error:errback } );
860 
861  var c = {};
862  c[library] = true;
863 
864  this.send("code",c);
865  },
866  */
867 
878  postRequestLock: function(path,data)
879  {
880  var u = {};
881  u[path] = data;
882 
883  //console.log("Post request lock!",arguments);
884  this.send("requestlock", u);
885  },
886 
897  postReleaseLock: function(path,data)
898  {
899  var u = {};
900  u[path] = data;
901 
902  //console.log("Post release lock!",arguments);
903  this.send("releaselock", u);
904  },
905 
917  currentPaneTrigger: function(event,trigger, exclude=null)
918  {
919  for (var t in trigger)
920  {
921  switch(t)
922  {
923  case "submit": //console.log("would post update:");
924  //console.log(trigger[t]);
925  this.postUpdate( trigger[t] );
926  break;
927 
928  case "submit+": //console.log("would post update:");
929  this.postUpdate( trigger[t] );
930  for (var p in trigger[t])
931  objectRegistry.applyDiff(p,trigger[t][p],null,exclude);
932  break;
933 
934  //default: console.warn("Unknown trigger action: "+t);
935  // break;
936  }
937  }
938  },
939 
952  saveInterface: function(layout)
953  {
954  //console.trace("Save interface!");
955  //console.log(layout);
956 
957 
958  if ( ! preferences.fetch("saveLayout",true) )
959  {
960  //console.log("saveLayout is off!");
961  return;
962  }
963 
964  this._batches.saveLayout.data = layout;
965 
966  if (!this._batches.saveLayout.timer)
967  { var THIS = this;
968  //this._batches.saveLayout.timer = setTimeout( function() {
969  this._batches.saveLayout.timer = requestAnimationFrame( function() {
970  if (THIS._batches.saveLayout.data)
971  {
972  var s = {};
973  s[config.interfacePath] = THIS._batches.saveLayout.data;
974 
975  THIS.send("write",s);
976  THIS._batches.saveLayout = { timer:null, data:null };
977  }
978  } );
979  }
980  },
981 
992  subscribe: function( paths )
993  {
994  //console.log("subscribing: ");
995  //console.trace(paths);
996 
997  while(paths.length)
998  {
999  var p = utils.cleanPath( paths.pop() );
1000 
1001  if (!this._batches.subscribe.data[p])
1002  this._batches.subscribe.data[p]=0;
1004  this._batches.subscribe.data[p]++;
1005  }
1006 
1007  if (!this._batches.subscribe.timer)
1008  { var THIS = this;
1009  //this._batches.subscribe.timer = setTimeout( function() {
1010  this._batches.subscribe.timer = requestAnimationFrame( function() {
1011  //console.log("would send: ");
1012  //console.log(THIS._subscribeBatch);
1013  THIS.send("subscribe", THIS._batches.subscribe.data);
1014  THIS._batches.subscribe = { timer:null, data:{} };
1015  } );
1016  //}, 0 );
1017  }
1018  },
1019 
1029  unsubscribe: function( paths, now )
1030  {
1031  //console.log("unsubscribing",paths);
1032 
1033  var THIS = this;
1034 
1035  while (paths.length)
1036  {
1037  var p = utils.cleanPath( paths.pop() );
1038 
1039  if (!this._batches.unsubscribe.data[p])
1040  this._batches.unsubscribe.data[p] = 0;
1041 
1042  this._batches.unsubscribe.data[p]++;
1043  }
1044 
1045  if (now)
1046  {
1047  if (this._batches.unsubscribe.timer)
1048  clearTimeout( this._batches.unsubscribe.timer );
1049 
1050  THIS.send("unsubscribe", THIS._batches.unsubscribe.data);
1051  THIS._batches.unsubscribe = { timer:null, data:{} };
1052  }
1053 
1054  if (!this._batches.unsubscribe.timer && !now)
1055  {
1056  this._batches.unsubscribe.timer = requestAnimationFrame( function()
1057  {
1058  THIS.send("unsubscribe", THIS._batches.unsubscribe.data);
1059  THIS._batches.unsubscribe = { timer:null, data:{} };
1060  } );
1061  }
1062  },
1063 
1073  read: function( paths )
1074  {
1075  while (paths.length)
1076  {
1077  var p = utils.cleanPath( paths.pop() );
1078 
1079  if (!this._batches.read.data[p])
1080  this._batches.read.data[p] = 0;
1081 
1082  this._batches.read.data[p]++;
1083  }
1084 
1085  if (!this._batches.read.timer)
1086  { var THIS = this;
1087  //this._batches.read.timer = setTimeout( function() {
1088  this._batches.read.timer = requestAnimationFrame( function() {
1089  THIS.send("read", THIS._batches.read.data);
1090  THIS._batches.read = { timer:null, data:{} };
1091  } );
1092  //}, 0 );
1093  }
1094  },
1095 
1106  readSingle: function( path, metadata )
1107  {
1108  var s = {};
1109  s[path] = metadata || {};
1110 
1111  this.send("read", s);
1112  },
1113 
1123  metadata: function( paths )
1124  {
1125  while (paths.length)
1126  {
1127  var p = utils.cleanPath( paths.pop() );
1128 
1129  if (!this._batches.metadata.data[p])
1130  this._batches.metadata.data[p] = 0;
1131 
1132  this._batches.metadata.data[p]++;
1133  //console.log( paths.pop() );
1134  }
1135 
1136  if (!this._batches.metadata.timer)
1137  { var THIS = this;
1138  //this._batches.metadata.timer = setTimeout( function() {
1139  this._batches.metadata.timer = requestAnimationFrame( function() {
1140  THIS.send("metadata", THIS._batches.metadata.data);
1141  THIS._batches.metadata = { timer:null, data:{} };
1142  } );
1143  //}, 0 );
1144  }
1145  },
1146 
1155  openUserPreferences: function( )
1156  {
1157  if (modal.showing)
1158  return;
1159 
1160  //paneManager.openModal( config.preferencesPath, "Preferences for "+config.realname+" (<span style='text-transform:none;'>"+config.username+"</span>)", { width:400, height:190 }, { base:config.preferencesBase } );
1161  paneManager.openModal( config.preferencesPath, "Preferences for "+config.realname+" (<span style='text-transform:none;'>"+config.username+"</span>)", { width:400, height:"expand", resize:false }, { base:config.preferencesBase } );
1162  }
1163  };
1164 
1165  return vfsClient;
1166  }
1167 );
1168 
1169 
applySubscription(data, metadata)
getter id
returns the number of milliseconds since midnight January 1, 1970 UTC
DOCME.
setter user
a setter DOCME
footer()
DOCME.
Form renderer.
Manages context menus or any other menu.
resetMenus()
DOCME.
setter name
a setter DOCME
setter type
a setter DOCME
isRegistered(id, object)
applyDiff(id, diff, user, except)
applyRequestSuccess(command, id, data, metadata)
applyRequestError(command, id, reason)
applySubscription(id, data, metadata)
applyMetadata(id, metadata)
applyReleaseLock(id, data)
applyRead(id, data, metadata)
registerObject(id, o, nosubscribe)
Register an object in the registry, and call the pathAddedCallback.
applyRequestLock(id, data)
The paneFactory dynamically loads pane definitions and registers them to create new pane instances.
setter postUpdate
Assign a callback to the paneFactory class for VFS_node::submit() commands.
setter postReleaseLock
Assign a callback to the paneFactory class for VFS_node::releaseLock() commands.
paneFactory(layout, callback)
Create a pane or paneLoader, and execute the callback once complete.
setter postDelete
Assign a callback to the paneFactory class for VFS_node::rm() commands.
setter postRequestLock
Assign a callback to the paneFactory class for VFS_node::requestLock() commands.
setter postCreate
Assign a callback to the paneFactory class for VFS create() commands.
pane(layout, object)
The paneManager manages panes in a user layout.
openApplicationLayout(event, context, template, metadata)
pathDeleteCallback()
A callback to use for deleting entries in the VFS based on a path.
reset()
DOCME.
openModal(path, title, size, context)
pathSubmitCallback()
DOCME.
pathAddedCallback()
DOCME.
setter config
a setter DOCME
openModalForm(path, form, title, size, context, metadata)
initialize()
DOCME.
pathRemovedCallback()
DOCME.
saveCallback()
DOCME.
objectDestroy(pane)
objectFactory(layout)
pathCreateCallback()
A callback to use for creating new entries in the VFS based on a path.
createPane(path)
Create a pane based on path.
getter path
a getter DOCME
applyRequestSuccess()
If an adminstrator has deleted his own preferences, this function will be called on success.
fetch(v, _default)
resize()
Does nothing.
applyDiff(diff, user)
update(dirty)
Process the _queue and apply the settings.
Utility functions for javascript clients.
cleanPath(path)
Clean and normalize a resource path.
The vfsClient manages a connection to the VFS.
readSingle(path, metadata)
saveLayoutPrompt()
openUserPreferences()
If the modal is not already showing, open the preferences.
applyLayoutHandler(menuData, data)
subscribe(paths)
This will aggregate paths for subscription, using a timer of 0.
splitLayout(which)
currentPaneTrigger(event, trigger, exclude=null)
deleteLayoutHandler(tab, data)
refineLayoutModal()
createPaneByPathHandler()
unsubscribe(paths)
saveLayoutHandler(name)
postLSRequest(event, params)
saveInterface(layout)
Queue the layout to be saved as soon as control returns.
initializeUI(userinfo)
metadata(paths)
read(paths)
destroyPane(pane)
send(command, attributes)
createPaneHandler(tab, data)
vfsClient(_config, bootstrap)