Ticket #420: ticket420.patch

File ticket420.patch, 14.1 kB (added by MartinBudden, 10 months ago)
  • js/Story.js

     
    129129//#   tiddlerElem - reference to the element that will contain the tiddler 
    130130Story.prototype.loadMissingTiddler = function(title,fields,tiddlerElem) 
    131131{ 
     132        var getTiddlerCallback = function(context) 
     133        { 
     134                var t = context.tiddler; 
     135                if(t && t.text) { 
     136                        if(!t.created) 
     137                                t.created = new Date(); 
     138                        if(!t.modified) 
     139                                t.modified = t.created; 
     140                        store.saveTiddler(t.title,t.title,t.text,t.modifier,t.modified,t.tags,t.fields,true,t.created); 
     141                        autoSaveChanges(); 
     142                } 
     143                context.adaptor.close(); 
     144                delete context.adpator; 
     145        }; 
    132146        var tiddler = new Tiddler(title); 
    133147        tiddler.fields = typeof fields == "string" ?  fields.decodeHashMap() : (fields ? fields : {}); 
    134         var serverType = tiddler.getServerType(); 
    135         var host = tiddler.fields['server.host']; 
    136         var workspace = tiddler.fields['server.workspace']; 
    137         if(!serverType || !host) 
    138                 return null; 
    139         var sm = new SyncMachine(serverType,{ 
    140                         start: function() { 
    141                                 return this.openHost(host,"openWorkspace"); 
    142                         }, 
    143                         openWorkspace: function() { 
    144                                 return this.openWorkspace(workspace,"getTiddler"); 
    145                         }, 
    146                         getTiddler: function() { 
    147                                 return this.getTiddler(title,"onGetTiddler"); 
    148                         }, 
    149                         onGetTiddler: function(context) { 
    150                                 var tiddler = context.tiddler; 
    151                                 if(tiddler && tiddler.text) { 
    152                                         var downloaded = new Date(); 
    153                                         if(!tiddler.created) 
    154                                                 tiddler.created = downloaded; 
    155                                         if(!tiddler.modified) 
    156                                                 tiddler.modified = tiddler.created; 
    157                                         store.saveTiddler(tiddler.title,tiddler.title,tiddler.text,tiddler.modifier,tiddler.modified,tiddler.tags,tiddler.fields,true,tiddler.created); 
    158                                         autoSaveChanges(); 
    159                                 } 
    160                                 delete this; 
    161                                 return true; 
    162                         }, 
    163                         error: function(message) { 
    164                                 displayMessage("Error loading missing tiddler from %0: %1".format([host,message])); 
    165                         } 
    166                 }); 
    167         sm.go(); 
    168         return config.messages.loadingMissingTiddler.format([title,serverType,host,workspace]); 
     148        context = {}; 
     149        context.serverType = tiddler.getServerType(); 
     150        if(!context.serverType) 
     151                return; 
     152        context.host = tiddler.fields['server.host']; 
     153        context.workspace = tiddler.fields['server.workspace']; 
     154        var adaptor = new config.adaptors[context.serverType]; 
     155        adaptor.getTiddler(title,context,null,getTiddlerCallback); 
     156        return config.messages.loadingMissingTiddler.format([title,context.serverType,context.host,context.workspace]); 
    169157}; 
    170158 
    171159//# Overridable for choosing the name of the template to apply for a tiddler 
  • js/FileAdaptor.js

     
    11//-- 
    2 //-- Server adaptor for talking to static files 
     2//-- Server adaptor for talking to static TiddlyWiki files 
    33//-- 
    44 
    55function FileAdaptor() 
     
    99        return this; 
    1010} 
    1111 
    12 FileAdaptor.NotLoadedError = "TiddlyWiki file has not been loaded"; 
    1312FileAdaptor.serverType = 'file'; 
    1413 
    15 // Open the specified host/server 
     14FileAdaptor.prototype.setContext = function(context,userParams,callback) 
     15{ 
     16        if(!context) context = {}; 
     17        context.userParams = userParams; 
     18        if(callback) context.callback = callback; 
     19        context.adaptor = this; 
     20        if(!context.host) 
     21                context.host = this.host; 
     22        context.host = FileAdaptor.fullHostName(context.host); 
     23        if(!context.workspace) 
     24                context.workspace = this.workspace; 
     25        return context; 
     26}; 
     27 
     28FileAdaptor.fullHostName = function(host) 
     29{ 
     30        if(!host) 
     31                return ''; 
     32        if(!host.match(/:\/\//)) 
     33                host = 'http://' + host; 
     34        return host; 
     35}; 
     36 
     37FileAdaptor.minHostName = function(host) 
     38{ 
     39        return host ? host.replace(/^http:\/\//,'').replace(/\/$/,'') : ''; 
     40}; 
     41 
     42// Open the specified host 
    1643//#   host - url of host (eg, "http://www.tiddlywiki.com/" or "www.tiddlywiki.com") 
    1744//#   context is itself passed on as a parameter to the callback function 
     45//#   userParams - user settable object object that is passed on unchanged to the callback function 
    1846//#   callback - optional function to be called on completion 
    1947//# Return value is true if the request was successfully issued, false if this connector doesn't support openHost(), 
    2048//#   or an error description string if there was a problem 
    2149//# The callback parameters are callback(context) 
    2250//#   context.status - true if OK, string if error 
    2351//#   context.adaptor - reference to this adaptor object 
    24 //#   context - parameters as originally passed into the openHost function 
     52//#   userParams - parameters as originally passed into the openHost function 
    2553FileAdaptor.prototype.openHost = function(host,context,userParams,callback) 
    2654{ 
    2755        this.host = host; 
    28         if(!context) 
    29                 context = {}; 
    30         context.adaptor = this; 
    31         context.callback = callback; 
    32         context.userParams = userParams; 
    33         var ret = loadRemoteFile(host,FileAdaptor.openHostCallback,context); 
    34         return typeof(ret) == "string" ? ret : true; 
     56        context = this.setContext(context,userParams,callback); 
     57        context.status = true; 
     58        if(callback) 
     59                window.setTimeout(function() {callback(context,userParams);},10); 
     60        return true; 
    3561}; 
    3662 
    37 FileAdaptor.openHostCallback = function(status,context,responseText,url,xhr) 
     63FileAdaptor.loadTiddlyWikiCallback = function(status,context,responseText,url,xhr) 
    3864{ 
    39         var adaptor = context.adaptor; 
    4065        context.status = status; 
    4166        if(!status) { 
    4267                context.statusText = "Error reading file: " + xhr.statusText; 
    4368        } else { 
    44                 // Load the content into a TiddlyWiki() object 
    45                 adaptor.store = new TiddlyWiki(); 
    46                 if(!adaptor.store.importTiddlyWiki(responseText)) 
     69                //# Load the content into a TiddlyWiki() object 
     70                context.adaptor.store = new TiddlyWiki(); 
     71                if(!context.adaptor.store.importTiddlyWiki(responseText)) 
    4772                        context.statusText = config.messages.invalidFileError.format([url]); 
    4873        } 
    49         context.callback(context,context.userParams); 
     74        context.complete(context,context.userParams); 
    5075}; 
    5176 
    52 // Gets the list of workspaces on a given server 
    53 //#   context is itself passed on as a parameter to the callback function 
    54 //#   callback - optional function to be called on completion 
     77// Get the list of workspaces on a given server 
     78//#   context - passed on as a parameter to the callback function 
     79//#   userParams - user settable object object that is passed on unchanged to the callback function 
     80//#   callback - function to be called on completion 
    5581//# Return value is true if the request was successfully issued, false if this connector doesn't support getWorkspaceList(), 
    5682//#   or an error description string if there was a problem 
    57 //# The callback parameters are callback(context) 
     83//# The callback parameters are callback(context,userParams) 
    5884//#   context.status - true if OK, false if error 
    5985//#   context.statusText - error message if there was an error 
    6086//#   context.adaptor - reference to this adaptor object 
    61 //#   context - parameters as originally passed into the getWorkspaceList function 
     87//#   userParams - parameters as originally passed into the getWorkspaceList function 
    6288FileAdaptor.prototype.getWorkspaceList = function(context,userParams,callback) 
    6389{ 
    64         if(!context) 
    65                 context = {}; 
     90        context = this.setContext(context,userParams,callback); 
    6691        context.workspaces = [{title:"(default)"}]; 
    6792        context.status = true; 
    68         window.setTimeout(function() {callback(context,userParams);},10); 
     93        if(callback) 
     94                window.setTimeout(callback,10,context,userParams); 
    6995        return true; 
    7096}; 
    7197 
    7298// Open the specified workspace 
    7399//#   workspace - name of workspace to open 
     100//#   context - passed on as a parameter to the callback function 
     101//#   userParams - user settable object object that is passed on unchanged to the callback function 
    74102//#   callback - function to be called on completion 
    75 //#   context - passed to callback function 
    76103//# Return value is true if the request was successfully issued 
    77104//#   or an error description string if there was a problem 
    78 //# The callback parameters are callback(status,adaptor,context) 
    79 //#   status - true if OK, string if error 
    80 //#   adaptor - reference to this adaptor object 
    81 //#   context - parameters as originally passed into the openWorkspace function 
     105//# The callback parameters are callback(context,userParams) 
     106//#   context.status - true if OK, false if error 
     107//#   context.statusText - error message if there was an error 
     108//#   context.adaptor - reference to this adaptor object 
     109//#   userParams - parameters as originally passed into the openWorkspace function 
    82110FileAdaptor.prototype.openWorkspace = function(workspace,context,userParams,callback) 
    83111{ 
    84         if(!context) 
    85                 context = {}; 
     112        this.workspace = workspace; 
     113        context = this.setContext(context,userParams,callback); 
    86114        context.status = true; 
    87         window.setTimeout(function() {callback(context,userParams);},10); 
     115        if(callback) 
     116                window.setTimeout(callback,10,context,userParams); 
    88117        return true; 
    89118}; 
    90119 
    91120// Gets the list of tiddlers within a given workspace 
    92 //#   context - passed on to callback function 
    93 //#   userParams - user parameters passed through to the callback function 
     121//#   context - passed on as a parameter to the callback function 
     122//#   userParams - user settable object object that is passed on unchanged to the callback function 
    94123//#   callback - function to be called on completion 
    95124//#   filter - filter expression 
    96125//# Return value is true if the request was successfully issued, 
    97126//#   or an error description string if there was a problem 
    98 //# The callback parameters are callback(status,adaptor,context,tiddlerList) 
    99 //#   status - true if OK, false if error 
    100 //#   adaptor - reference to this adaptor object 
    101 //#   context - parameters as originally passed into the getTiddlerList function 
     127//# The callback parameters are callback(context,userParams) 
     128//#   context.status - true if OK, false if error 
     129//#   context.statusText - error message if there was an error 
     130//#   context.adaptor - reference to this adaptor object 
    102131//#   context.tiddlers - array of tiddler objects 
     132//#   userParams - parameters as originally passed into the getTiddlerList function 
    103133FileAdaptor.prototype.getTiddlerList = function(context,userParams,callback,filter) 
    104134{ 
    105         if(!this.store) 
    106                 return FileAdaptor.NotLoadedError; 
    107         if(!context) 
    108                 context = {}; 
    109         if(filter) { 
    110                 context.tiddlers = this.store.filterTiddlers(filter); 
     135        context = this.setContext(context,userParams,callback); 
     136        if(!context.filter) 
     137                context.filter = filter; 
     138        context.complete = FileAdaptor.getTiddlerListComplete; 
     139        return this.store ?  
     140                context.complete(context,context.userParams) : 
     141                loadRemoteFile(context.host,FileAdaptor.loadTiddlyWikiCallback,context); 
     142}; 
     143 
     144FileAdaptor.getTiddlerListComplete = function(context,userParams) 
     145{ 
     146        if(context.filter) { 
     147                context.tiddlers = context.adaptor.store.filterTiddlers(context.filter); 
    111148        } else { 
    112149                context.tiddlers = []; 
    113                 this.store.forEachTiddler(function(title,tiddler) {context.tiddlers.push(tiddler);}); 
     150                context.adaptor.store.forEachTiddler(function(title,tiddler) {context.tiddlers.push(tiddler);}); 
    114151        } 
    115         for(var t=0; t<context.tiddlers.length; t++) { 
    116                 context.tiddlers[t].fields['server.page.revision'] = context.tiddlers[t].modified.convertToYYYYMMDDHHMM(); 
     152        for(var i=0; i<context.tiddlers.length; i++) { 
     153                context.tiddlers[i].fields['server.type'] = FileAdaptor.serverType; 
     154                context.tiddlers[i].fields['server.host'] = FileAdaptor.minHostName(context.host); 
     155                context.tiddlers[i].fields['server.page.revision'] = context.tiddlers[i].modified.convertToYYYYMMDDHHMM(); 
    117156        } 
    118157        context.status = true; 
    119         window.setTimeout(function() {callback(context,userParams);},10); 
     158        if(context.callback) { 
     159                window.setTimeout(context.callback,10,context,userParams); 
     160        } 
    120161        return true; 
    121162}; 
    122163 
     
    127168        return info; 
    128169}; 
    129170 
    130 // Retrieves a tiddler from a given workspace on a given server 
     171// Retrieve a tiddler from a given workspace on a given server 
    131172//#   title - title of the tiddler to get 
     173//#   context - passed on as a parameter to the callback function 
     174//#   userParams - user settable object object that is passed on unchanged to the callback function 
    132175//#   callback - function to be called on completion 
    133 //#   context - passed on as a parameter to the callback function 
    134176//# Return value is true if the request was successfully issued, 
    135177//#   or an error description string if there was a problem 
    136 //# The callback parameters are callback(status,adaptor,context,tiddler) 
    137 //#   status - true if OK, false if error 
    138 //#   adaptor - reference to this adaptor object 
    139 //#   context - as passed into the function 
    140 //#   tiddler - the retrieved tiddler, or null if it cannot be found 
     178//# The callback parameters are callback(context,userParams) 
     179//#   context.status - true if OK, false if error 
     180//#   context.statusText - error message if there was an error 
     181//#   context.adaptor - reference to this adaptor object 
     182//#   context.tiddler - the retrieved tiddler, or null if it cannot be found 
     183//#   userParams - parameters as originally passed into the getTiddler function 
    141184FileAdaptor.prototype.getTiddler = function(title,context,userParams,callback) 
    142185{ 
    143         if(!this.store) 
    144                 return FileAdaptor.NotLoadedError; 
    145         if(!context) 
    146                 context = {}; 
    147         context.tiddler = this.store.fetchTiddler(title); 
    148         if(context.tiddler) { 
    149                 context.tiddler.fields['server.type'] = FileAdaptor.serverType; 
    150                 context.tiddler.fields['server.host'] = this.host; 
    151                 context.tiddler.fields['server.page.revision'] = context.tiddler.modified.convertToYYYYMMDDHHMM(); 
    152         } 
     186        context = this.setContext(context,userParams,callback); 
     187        context.title = title; 
     188        context.complete = FileAdaptor.getTiddlerComplete; 
     189        return context.adaptor.store ?  
     190                context.complete(context,context.userParams) : 
     191                loadRemoteFile(context.host,FileAdaptor.loadTiddlyWikiCallback,context); 
     192}; 
     193 
     194FileAdaptor.getTiddlerComplete = function(context,userParams) 
     195{ 
     196        var t = context.adaptor.store.fetchTiddler(context.title); 
     197        t.fields['server.type'] = FileAdaptor.serverType; 
     198        t.fields['server.host'] = FileAdaptor.minHostName(context.host); 
     199        t.fields['server.page.revision'] = t.modified.convertToYYYYMMDDHHMM(); 
     200        context.tiddler = t; 
    153201        context.status = true; 
    154202        if(context.allowSynchronous) { 
    155203                context.isSynchronous = true; 
    156                 callback(context,userParams); 
     204                context.callback(context,userParams); 
    157205        } else { 
    158                 window.setTimeout(function() {callback(context,userParams);},10); 
     206                window.setTimeout(context.callback,10,context,userParams); 
    159207        } 
    160208        return true; 
    161209};