Changeset 200:22587cc7eed6

Show
Ignore:
Timestamp:
09/17/08 10:38:47 (18 months ago)
Author:
johnbywater
Branch:
default
convert_revision:
svn:10edda23-d834-0410-9182-b00384516d49/trunk@212
Message:

Added missing page controller specs. Cleaned up MVC codes. Cleaned up dependency loading. Fixed timeline part of timeline page. Removed old scripts folder.

Location:
microfacts
Files:
5 added
21 removed
19 modified

Legend:

Unmodified
Added
Removed
  • microfacts/controllers/factlet.py

    r195 r200  
    4949 
    5050        title = request.params.getone('title').strip() 
    51         url = request.params.getone('url').strip() 
     51        url = request.params.get('url', '').strip() 
    5252        if title: 
    5353            logger.debug('Creating new factlet with title: %s' % title) 
  • microfacts/controllers/thread.py

    r189 r200  
    7070            abort(mode.response_code) 
    7171 
    72     def read_timeline(self, id): 
     72    def read_timeline_old(self, id): 
    7373        c.has_inline_edit = False 
    7474        mode = EntityGet('/thread/%s' % id).execute() 
     
    8181                html = fc.read_core(id) 
    8282                c.factlet_info = genshi.XML(html) 
     83            self._set_json_payload() 
     84            return render('thread/read_timeline') 
     85        else: 
     86            abort(mode.response_code) 
     87 
     88    def read_timeline(self, id): 
     89        c.has_inline_edit = False 
     90        c.googlemaps_apikey = config.get('googlemaps_apikey', '') 
     91        mode = EntityGet('/thread/%s' % id).execute() 
     92        if mode.response_code == 200: 
     93            c.thread = mode.entity 
     94            if len(c.thread.factlets) > 0: 
     95                import microfacts.controllers.factlet 
     96                id = c.thread.factlets[0].id 
     97                fc = microfacts.controllers.factlet.FactletController() 
     98                html = fc.read_core(id) 
     99                c.factlet_info = genshi.XML(html) 
     100            self._set_json_payload() 
    83101            return render('thread/read_timeline') 
    84102        else: 
     
    87105    def read_geochrono(self, id): 
    88106        c.has_inline_edit = False 
     107        c.googlemaps_apikey = config.get('googlemaps_apikey', '') 
    89108        mode = EntityGet('/thread/%s' % id).execute() 
    90109        if mode.response_code == 200: 
  • microfacts/public/behaviour/app/controllers/geochronopage_controller.js

    r182 r200  
    2727 
    2828if (Environment != "test") { 
    29     // stub a console if it does not exist (so work if firebug is not available) 
    30     if (!console) { 
    31         var console = { 
    32             'log': function() { 
    33             }, 
    34             'error': function() { 
    35             } 
    36         }; 
    37     } 
    3829    window.addEvent('domready', function () { 
    3930        new GeochronoPageController(document); 
     
    4132} 
    4233 
    43 // for some reason just does not work ... 
    44 // BaseController.createPageController('GeochronoPageController'); 
  • microfacts/public/behaviour/app/controllers/threadpage_controller.js

    r182 r200  
    11var ThreadPageController = new Class({ 
    2     Extends: Controller, 
     2    Extends: BaseController, 
     3    name: 'ThreadPageController', 
    34 
    4     initialize: function (element) { 
    5         this.parent.apply(this, arguments); 
    6         this.initModel(); 
    7         console.log('ThreadPageController: initialize'); 
    8         this.controllers = []; 
    9         element.getElements('.thread-factlets').each(function (el) { 
    10             this.addController(new ThreadFactletsView(el)); 
     5    setupViews: function (element) { 
     6        this.element.getElements('#timeline').each(function (el) { 
     7            this.log("Creating timeline view for element:"); 
     8            this.log(el); 
     9            var view = new TimelineView(el); 
     10            this.addView(view); 
    1111        }, this); 
    12         // should be only one 
    13         element.getElements('#factlet-search').each(function (el) { 
    14             this.addController(new FactletSearchView(el)); 
    15         }, this); 
     12        this.log('Done'); 
    1613 
    17         this.thread = null; 
    18         this.threadFactlets = null; 
    19         this.selectedFactlet = null; 
    20         this.model.startWithThread(payloadThread, payloadThreadFactlets); 
    21     }, 
    22  
    23     initModel: function () { 
    24         this.model = new Model(); 
    25         this.model.addEvent('threadStart', this.onThreadStart.bind(this)); 
    26     }, 
    27  
    28     onThreadStart: function() { 
    29         console.log('ThreadPageController: onThreadStart'); 
    30         this.thread = arguments[0]; 
    31         this.threadFactlets = arguments[1]; 
    32         this.fireEvent('threadStart', arguments); 
    33     }, 
    34  
    35     onFactletSelect: function(factlet) { 
    36         console.log('ThreadPageController: saw factletSelect event'); 
    37         this.selectedFactlet = factlet; 
    38         this.fireEvent('factletSelect', factlet); 
    39     }, 
    40  
    41     onFactletAppend: function(factlet) { 
    42         console.log('ThreadPageController: saw factletAppend event'); 
    43         this.thread.data.factlets.push(factlet.id); 
    44         this.thread.save(); 
    45         // should really do this in response to hearing save event from model I think 
    46         this.threadFactlets.push(factlet); 
    47         this.onThreadStart(this.thread, this.threadFactlets); 
    48     }, 
    49  
    50     onFactletDelete: function(factlet) { 
    51         console.log('ThreadPageController: saw factletDelete event'); 
    52         var threadFactletIds = this.thread.data.factlets.filter(function(item) { 
    53                     return item != factlet.id; 
    54         }); 
    55         this.thread.data.factlets = threadFactletIds; 
    56         this.threadFactlets = this.threadFactlets.filter(function(item) { 
    57             return item.id != factlet.id; 
    58         }); 
    59         this.thread.save() 
    60         // this.fireEvent('factletDelete', factlet); 
    61         this.onThreadStart(this.thread, this.threadFactlets); 
    62     }, 
    63  
    64     onDomainObjectChange: function (domainObject) { 
    65         // TODO: check this is factlet data and relevant to us .... 
    66         if (domainObject.name == 'thread' && domainObject.id == this.thread.id) { 
    67             // TODO 
    68  
    69         } 
    70     }, 
    71  
    72     addController: function(controller) { 
    73         this.controllers.push(controller); 
    74         controller.addEvent('factletSelect', this.onFactletSelect.bind(this)); 
    75         controller.addEvent('factletAppend', this.onFactletAppend.bind(this)); 
    76  
    77         this.addEvent('factletSelect', controller.onFactletSelect.bind(controller)); 
    78         this.addEvent('threadStart', controller.onThreadStart.bind(controller)); 
    79     }, 
    80  
    81     controls: { 
    82         '#factlet-delete-submit click': function (e) { 
    83             console.log('Factlet Delete Button clicked.'); 
    84             var evt = new Event(e); 
    85             evt.stop(); 
    86             if (this.selectedFactlet) { 
    87  
    88                 this.onFactletDelete(this.selectedFactlet); 
    89             } 
    90         } 
     14        this.model.startWithThread( 
     15            payloadThread,         // From HTML doc. 
     16            payloadThreadFactlets  // From HTML doc. 
     17        ); 
    9118    } 
     19     
    9220}); 
    9321 
    9422if (Environment != "test") { 
    95     // stub a console if it does not exist (so work if firebug is not available) 
    96     if (!console) { 
    97         var console = { 
    98             'log': function() { 
    99             }, 
    100             'error': function() { 
    101             } 
    102         }; 
    103     } 
    10423    window.addEvent('domready', function () { 
    105         // using document as argument causes problems 
    106         // as document is somehow special (cannot do delegate on it for example) 
    107         // so for moment look up body and use that 
    108         // new ThreadPageController(document); 
    109         new ThreadPageController($$('body')[0]); 
     24        new ThreadPageController(document); 
    11025    }); 
    11126} 
     27 
  • microfacts/public/behaviour/app/controllers/threadreadpage_controller.js

    r184 r200  
    55    setupViews: function (element) { 
    66        this.element.getElements('.factlet-details').each(function (el) { 
    7             console.log("Creating factlet details view for element:"); 
     7            this.log("Creating factlet details view for element:"); 
    88            this.log(el); 
    99            var view = new FactletDetailsView(el); 
     
    1111        }, this); 
    1212        this.element.getElements('.thread-factlets').each(function (el) { 
    13             console.log("Creating thread factlets view for element:"); 
     13            this.log("Creating thread factlets view for element:"); 
    1414            this.log(el); 
    1515            var view = new ThreadFactletsView(el); 
     
    2626}); 
    2727 
    28 if (Environment != "test") { 
    29     // stub a console if it does not exist (so work if firebug is not available) 
    30     if (!console) { 
    31         var console = { 
    32             'log': function() { 
    33             }, 
    34             'error': function() { 
    35             } 
    36         }; 
    37     } 
    38     window.addEvent('domready', function () { 
    39         new ThreadReadPageController(document); 
    40     }); 
    41 } 
    42  
  • microfacts/public/behaviour/app/microfacts.js

    r141 r200  
     1systemUnderTest = true; 
     2 
    13// var DEBUGLEVEL = 3; 
    24//  
  • microfacts/public/behaviour/app/views/factletdetailsview.js

    r187 r200  
    11var FactletDetailsView = new Class({ 
    22    // Extends: Controller, 
    3     Extends: BaseControlsView, 
     3    Extends: EventDelegationView, 
    44    name: 'FactletDetailsView', 
    55     
     
    1616 
    1717    renderDetails: function(responseTree, responseElements, responseHTML) { 
    18         console.log(this.name + ' renderDetails'); 
    19         // console.log(responseTree[1]); 
     18        this.log(this.name + ' renderDetails'); 
     19        // this.log(responseTree[1]); 
    2020        // this.element.innerHTML = responseHTML; 
    2121        // var tmp = document.createElement('div'); 
    22         console.log(responseElements); 
    23         var newNode = responseElements[0]; 
    24         console.log(newNode); 
    25         this.element.parentNode.replaceChild(newNode, this.element); 
    26         this.element = newNode; 
     22        this.log(responseElements); 
     23        if (responseElements) { 
     24            var newNode = responseElements[0]; 
     25            this.log(newNode); 
     26            this.element.parentNode.replaceChild(newNode, this.element); 
     27            this.element = newNode; 
     28        } 
    2729    }, 
    2830 
  • microfacts/public/behaviour/app/views/factletsearchview.js

    r191 r200  
    11var FactletSearchView = new Class({ 
    2     // Extends: Controller, 
    3     Extends: BaseControlsView, 
     2    Extends: EventDelegationView, 
    43    name: 'FactletSearchView', 
    54     
  • microfacts/public/behaviour/app/views/mapview.js

    r176 r200  
     1var googlemaps_apikey = ''; 
     2//var googlemaps_apikey = 'ABQIAAAARZ8-8aLLq6MZvE0jrVASkxQChx54JYdgbPKio935j7RDK0bGdhQBc5WnLOdkVx49SOALTkpfYB9ORA'; 
     3 
    14var MapView = new Class({ 
     5    name: 'MapView', 
    26    Extends: BaseView, 
    3     name: 'MapView', 
    47 
    58    setupView: function () { 
    69        this.map = new OpenLayers.Map(this.element.id); 
    7         this.baseLayer = new OpenLayers.Layer.WMS( 
    8             "OpenLayers WMS",  
    9             "http://labs.metacarta.com/wms/vmap0", 
    10             {layers: 'basic'} 
    11         ); 
     10        if ($chk( googlemaps_apikey )) { 
     11            this.baseLayer = new OpenLayers.Layer.Google( 
     12                "Google Physical", 
     13                {type: G_PHYSICAL_MAP} 
     14            ); 
     15        } else { 
     16            this.baseLayer = new OpenLayers.Layer.WMS( 
     17                "OpenLayers WMS",  
     18                "http://labs.metacarta.com/wms/vmap0", 
     19                {layers: 'basic'} 
     20            ); 
     21        } 
     22  
    1223        var SHADOW_Z_INDEX = 10; 
    1324        var MARKER_Z_INDEX = 11; 
    14   
    1525        this.markerLayer = new OpenLayers.Layer.Vector( 
    1626            "Marker Drop Shadows",  
     
    5363        this.selectControl.activate(); 
    5464 
    55         var lon = 0; 
    56         var lat = 0; 
    57         var zoom = 2; 
    58         this.map.setCenter(new OpenLayers.LonLat(lon, lat), zoom); 
     65        //var lon = 0; 
     66        //var lat = 0; 
     67        //var zoom = 2; 
     68        //this.map.setCenter(new OpenLayers.LonLat(lon, lat), zoom); 
    5969    }, 
    6070     
     
    6272        var featuresData = this.factletsToGeoJson(factletsData); 
    6373        this.drawGeoJson(featuresData); 
    64         //this.zoomToFactletsExtent(factlets); 
    65         this.map.zoomToMaxExtent(); 
     74        this.zoomToFactletsExtent(factletsData); 
     75        //this.map.zoomToMaxExtent(); 
    6676    }, 
    6777 
     
    128138                } 
    129139            } 
    130         }); 
     140        }, this); 
    131141        var bounds = new OpenLayers.Bounds(); 
    132142        bounds.extend(new OpenLayers.LonLat(minLon, minLat)); 
     
    135145        this.log(bounds); 
    136146        this.map.zoomToExtent(bounds); 
    137         this.map.zoomToScale(0); 
     147        //this.map.zoomToScale(0); 
    138148    }, 
    139149 
  • microfacts/public/behaviour/app/views/threadfactletsview.js

    r191 r200  
    11var ThreadFactletsView = new Class({ 
    2     Extends: BaseControlsView, 
     2    Extends: EventDelegationView, 
    33 
    44    factletSummaryTemplate: [ 
     
    2020     
    2121    onFactletSelect: function (factlet) { 
    22         console.log("ThreadFactletsController saw factletSelect event"); 
     22        this.log("ThreadFactletsController saw factletSelect event"); 
    2323        this.selectedFactletId = factlet.id; 
    2424        // TODO: unselect any selected element ... 
     
    2626            value.removeClass('active');  
    2727        }); 
    28         var div = this.factletDivsKeyedById[factlet.id]; 
    29         div.addClass('active'); 
     28        if (this.factletDivsKeyedById.has(factlet.id)) { 
     29            var div = this.factletDivsKeyedById[factlet.id]; 
     30            div.addClass('active'); 
     31        } 
    3032    }, 
    3133 
    3234    // TODO: refactor to use BaseView class onThreadStart 
    3335    onThreadStart: function (thread, threadFactlets) { 
    34         console.log("ThreadFactletsController saw threadStart event"); 
     36        this.log("ThreadFactletsController saw threadStart event"); 
    3537        // no specific initializing here so just do update 
    3638        this.onThreadUpdate(thread, threadFactlets); 
    37         console.log('ThreadFactletsController: end'); 
     39        this.log('ThreadFactletsController: end'); 
    3840    }, 
    3941 
     
    4648        this.factlets.each(function(fct) { 
    4749            this.factletsKeyedById[fct.id] = fct; 
    48             // Create ourselves so work on update too 
     50            // Generate factlet HTML. 
    4951            var dummy = document.createElement('div'); 
    5052            fctdivHTML = this.generateFactletHtml(fct.data); 
     
    5254            var fctdiv = dummy.childNodes[0]; 
    5355            this.element.appendChild(fctdiv); 
    54             // now associate each factlet with its element 
    55             // var divId = 'factlet-' + fct.id; 
    56             // var fctdiv = $(divId); 
    5756            this.factletDivsKeyedById[fct.id] = fctdiv; 
    5857        }, this); 
  • microfacts/public/behaviour/lib/moovc.js

    r191 r200  
    1 var LayerBase = new Class({ 
     1// 
     2//  MooVC means Model-View-Controller with Mootools. 
     3// 
     4 
     5// Layer base class. 
     6var MoovcBase = new Class({ 
     7    name: 'MoovcBase',  // Introspection dreams. :-) 
    28    Implements: [Events, Options], 
    3  
     9     
    410    log: function(message) { 
    511        console.log(message); 
    612    }, 
    7  
     13     
    814    error: function(message) { 
    915        console.error(message); 
    1016    } 
    11  
    12 }); 
     17}); 
     18 
     19 
     20// 
     21//  MooVC model classes. 
     22// 
    1323 
    1424var BaseModel = new Class({ 
    15     Extends: LayerBase 
    16  
    17 }); 
     25    name: 'BaseModel', 
     26    Extends: MoovcBase 
     27}); 
     28 
     29// Domain model entity base class. 
     30var DomainObject = new Class({ 
     31    name: 'DomainObject', 
     32    Extends: BaseModel, 
     33     
     34    options: { 
     35        name: 'blank', 
     36        prefix: '', 
     37        urls: { 
     38           create: ':name', 
     39           read: ':name/:id', 
     40           update: ':name/:id', 
     41           delete: ':name/:id' 
     42        } 
     43    }, 
     44     
     45    initialize: function (id, options) { 
     46        this.id = id; 
     47        this.setOptions(options); 
     48        this.reload(); 
     49    }, 
     50     
     51    reload: function () { 
     52        this.request().get(this._urlFor('read')); 
     53    }, 
     54     
     55    save: function () { 
     56        // TODO: allow faked out PUT requests please =). 
     57        // this.request().put(this._urlFor('update'), this.data); 
     58        this.request().post(this._urlFor('update'), encodeURIComponent(JSON.encode(this.data))); 
     59    }, 
     60     
     61    delete: function () { 
     62        this.request().delete(this._urlFor('delete')); 
     63    }, 
     64     
     65    setData: function (data, json) { 
     66        this.data = data; 
     67        this.fireEvent('dataChange', this.data); 
     68        this.fireEvent('domainObjectChange', this); 
     69    }, 
     70 
     71    request: function (options) { 
     72        return new Request.JSON(this.requestOptions(options)) 
     73    }, 
     74     
     75    requestOptions: function (options) { 
     76        var defaults = { 
     77            onSuccess: this.setData.bind(this), 
     78            onFailure: this.requestFailure.bind(this) 
     79        } 
     80        return $merge(defaults, options); 
     81    }, 
     82     
     83    _urlFor: function (action) { 
     84        var url = '/'; 
     85        if ($chk(this.options.prefix)) { 
     86            url += this.options.prefix + '/'; 
     87        } 
     88        return url + this.options.urls[action].replace(/:name/g, this.options.name).replace(/:id/g, this.id); 
     89    }, 
     90 
     91    requestFailure: function (json) { 
     92        this.error("request failed!"); 
     93        this.error(arguments);    
     94    } 
     95}); 
     96 
     97// Establish the aggregating model registry. 
     98var Registry = new Class({ 
     99    name: 'Registry', 
     100    Extends: BaseModel, 
     101 
     102    startWithThread: function (payloadThread, payloadThreadFactlets) { 
     103        this.log('Registry: startWithThread'); 
     104        var thread = new Thread(payloadThread['id']); 
     105        thread.data = payloadThread; 
     106        var threadFactlets = []; 
     107        // ensure all thread factlet domain objects present 
     108        payloadThreadFactlets.each(function(payloadFactlet) { 
     109            // TODO: pass payloadFactlet into constructor 
     110            var factlet = new Factlet(payloadFactlet['id']); 
     111            factlet.data = payloadFactlet; 
     112            DomainObject.Register['Factlet'][factlet.id] = factlet; 
     113            threadFactlets.push(factlet); 
     114        }); 
     115        DomainObject.Register['Thread'][thread.id] = thread; 
     116        var evtData = [thread, threadFactlets]; 
     117        this.fireEvent('threadStart', evtData); 
     118    } 
     119}); 
     120 
     121 
     122// Add register-like functionality to registry. 
     123// TODO: Move this functionality from DomainObject to Registry. 
     124DomainObject.Register = { 'Thread': {}, 'Factlet': {} }; 
     125 
     126DomainObject.Resource = function (name, id) { 
     127    if ($type(DomainObject.Register[name]) != 'object') { 
     128        DomainObject.Register[name] = {}; 
     129    } 
     130    if (!$chk(DomainObject.Register[name][id])) { 
     131        // FIXME: don't use eval (or at least not in such a horrible way) 
     132        eval("var constructor = " + name); 
     133        DomainObject.Register[name][id] = new constructor(id) 
     134    } 
     135    return DomainObject.Register[name][id]; 
     136}; 
     137 
     138 
     139// 
     140//  MooVC view classes. 
     141// 
    18142 
    19143var BaseView = new Class({ 
    20     Extends: LayerBase, 
    21     name: 'BaseView',  // Introspection dreams. :-) 
     144    name: 'BaseView', 
     145    Extends: MoovcBase, 
    22146 
    23147    initialize: function (element) { 
     
    64188}); 
    65189 
    66 var BaseControlsView = new Class({ 
     190//  Introduce 'event delegation functionality' to base View. 
     191var EventDelegationView = new Class({ 
     192    name: 'EventDelegationView', 
    67193    Extends: BaseView, 
    68     name: 'BaseControlsView', 
    69194 
    70195    controls: {}, 
     
    74199        this.setControls(controls); 
    75200        this.delegateControls(); 
    76     }, 
    77  
    78     setupView: function () { 
    79201    }, 
    80202 
     
    100222}); 
    101223 
     224 
     225// 
     226//  MooVC Controller classes. 
     227// 
     228 
    102229var BaseController = new Class({ 
    103     Extends: LayerBase, 
    104230    name: 'BaseController', 
     231    Extends: MoovcBase, 
    105232 
    106233    initialize: function (element) { 
     
    113240 
    114241    initModel: function () { 
    115         this.model = new Model(); 
     242        this.model = new Registry(); 
    116243        this.model.addEvent('threadStart', this.onThreadStart.bind(this)); 
    117244    }, 
     
    149276 
    150277 
    151 // for some reason just does not work ... 
    152 BaseController.createPageController = function(controllerClassName) { 
    153     if (Environment != "test") { 
    154         // define a non-functional console function for when firebug is not available 
    155         if (!console) { 
    156             var console = { 
    157                 'log': function() { 
    158                 }, 
    159                 'error': function() { 
    160                 } 
    161             }; 
    162         } 
    163         window.addEvent('domready', function () { 
    164             eval("var constructor = " + controllerClassName); 
    165             new constructor(document) 
    166         }); 
    167     } 
    168 }; 
     278var EventDelegationController = new Class({ 
     279    name: 'EventDelegationController', 
     280    Extends: BaseController, 
     281 
     282    controls: {}, 
     283     
     284    initialize: function (element, controls) { 
     285        this.parent.apply(this, arguments); 
     286        this.element.store('app:controller', this); 
     287        this.views = []; 
     288        this.setControls(controls); 
     289        this.delegateControls(); 
     290    }, 
     291 
     292    setupViews: function () { 
     293    }, 
     294     
     295    setControls: function (controls) { 
     296        this.controls = $merge(this.controls, controls); 
     297    }, 
     298     
     299    delegateControls: function () { 
     300        $each(this.controls, function (fn, desc) { 
     301            var desc = desc.trim().split(" "), type = desc.pop(), selector = desc.join(" "); 
     302            if (this.element.delegate) { 
     303                this.element.delegate(selector, type, fn, this);  
     304            } 
     305        }, this); 
     306    }, 
     307     
     308    addDefaultListeners: function () { 
     309        this.model.addEvent('dataChange', this.dataChange.bind(this)); 
     310    }, 
     311     
     312    dataChange: function (data) { 
     313        this.render(); 
     314    }, 
     315     
     316    id: function () { 
     317        return $pick(this._id, (this._id = this.element.get('id').split('-').getLast())); 
     318    }, 
     319     
     320    render: function () { 
     321        this.views.each(function (v) { 
     322            v.render(this.element, this.model.data); 
     323        }, this); 
     324    } 
     325}); 
     326 
     327// What's this for? 
     328Element.implement({ 
     329    controller: function () { 
     330        return this.retrieve('app:controller'); 
     331    } 
     332}); 
  • microfacts/public/behaviour/load.js

    r184 r200  
    4848 
    4949loader.addModule({ 
     50    name: "delegator", 
     51    type: "js", 
     52    path: "lib/delegator.js?" + Math.random(), 
     53    varName: "Element.delegate", 
     54    requires: ['mootools'] 
     55}); 
     56 
     57loader.addModule({ 
    5058    name: "moovc", 
    5159    type: "js", 
     
    5361    requires: ['mootools', 'delegator'], 
    5462    varName: "LayerBase" 
    55 }); 
    56  
    57 loader.addModule({ 
    58     name: "model", 
    59     type: "js", 
    60     path: "app/models/model.js?" + Math.random(), 
    61     requires: ['moovc'], 
    62     varName: "Model" 
    63 }); 
    64  
    65 loader.addModule({ 
    66     name: "domainobject", 
    67     type: "js", 
    68     path: "lib/domainobject.js?" + Math.random(), 
    69     requires: ['moovc'], 
    70     varName: "DomainObject" 
    71 }); 
    72  
    73 loader.addModule({ 
    74     name: "view", 
    75     type: "js", 
    76     path: "lib/view.js?" + Math.random(), 
    77     requires: ['moovc'], 
    78     varName: "View" 
    79 }); 
    80  
    81 loader.addModule({ 
    82     name: "controller", 
    83     type: "js", 
    84     path: "lib/controller.js?" + Math.random(), 
    85     requires: ['mootools', 'delegator'], 
    86     varName: "Controller" 
    87 }); 
    88  
    89 loader.addModule({ 
    90     name: "delegator", 
    91     type: "js", 
    92     path: "lib/delegator.js?" + Math.random(), 
    93     varName: "Element.delegate", 
    94     requires: ['mootools'] 
    9563}); 
    9664 
     
    10371    type: "js", 
    10472    path: "app/models/factlet.js?" + Math.random(), 
    105     requires: ['domainobject'], 
     73    requires: ['moovc'], 
    10674    varName: "Factlet" 
    10775}); 
     
    11179    type: "js", 
    11280    path: "app/models/thread.js?" + Math.random(), 
    113     requires: ['domainobject'], 
     81    requires: ['moovc'], 
    11482    varName: "Thread" 
    115 }); 
    116  
    117 // ========= 
    118 // = Views = 
    119 // ========= 
    120  
    121 loader.addModule({ 
    122     name: "fillview", 
    123     type: "js", 
    124     path: "app/views/fillview.js?" + Math.random(), 
    125     requires: ['view', 'extensions'], 
    126     varName: "FillView" 
    127 }); 
    128  
    129  
    130 loader.addModule({ 
    131     name: "pagetitleview", 
    132     type: "js", 
    133     path: "app/views/pagetitleview.js?" + Math.random(), 
    134     requires: ['view'], 
    135     varName: "PageTitleView" 
    13683}); 
    13784 
     
    14087    type: "js", 
    14188    path: "app/views/factletdetailsview.js?" + Math.random(), 
    142     requires: ['view'], 
     89    requires: ['moovc'], 
    14390    varName: "FactletDetailsView" 
    14491}); 
     
    14895    type: "js", 
    14996    path: "app/views/threadfactletsview.js?" + Math.random(), 
    150     requires: ['view', 'controller', 'thread', 'ejs'], 
     97    requires: ['moovc', 'thread', 'ejs'], 
    15198    varName: "ThreadFactletsView" 
    15299}); 
     
    156103    type: "js", 
    157104    path: "app/views/factletsearchview.js?" + Math.random(), 
    158     requires: ['view', 'controller', 'factlet'], 
     105    requires: ['moovc', 'factlet'], 
    159106    varName: "FactletSearchView" 
    160107}); 
     
    176123}); 
    177124 
    178 // =============== 
    179 // = Controllers = 
    180 // =============== 
    181  
    182 loader.addModule({ 
    183     name: "microfactscontroller", 
    184     type: "js", 
    185     path: "app/controllers/microfacts_controller.js?" + Math.random(), 
    186     requires: ['controller'], 
    187     varName: "MicrofactsController" 
    188 }); 
    189  
    190 loader.addModule({ 
    191     name: "factletcontroller", 
    192     type: "js", 
    193     path: "app/controllers/factlet_controller.js?" + Math.random(), 
    194     requires: ['controller', 'factlet', 'fillview', 'pagetitleview'], 
    195     varName: "FactletController" 
    196 }); 
    197  
    198 // ================ 
    199 // = Application! = 
    200 // ================ 
    201  
    202 loader.addModule({ 
    203     name: "microfacts", 
    204     type: "js", 
    205     path: "app/microfacts.js?" + Math.random(), 
    206     requires: ['domainobject', 'view', 'controller', 'microfactscontroller', 'factletcontroller', 'factletdetailsview', 'threadfactletsview', 'mapview', 'timelineview', 'geochronopagecontroller', 'threadpagecontroller'], 
    207     varName: "Microfacts" 
    208 }); 
    209  
    210125loader.addModule({ 
    211126    name: "threadreadpagecontroller", 
    212127    type: "js", 
    213128    path: "app/controllers/threadreadpage_controller.js?" + Math.random(), 
    214     requires: ['model', 'domainobject', 'view', 'controller', 'thread', 'factlet', 'threadfactletsview', 'factletdetailsview'], 
     129    requires: ['moovc', 'thread', 'factlet', 'threadfactletsview', 'factletdetailsview'], 
    215130    varName: "ThreadReadPageController" 
     131}); 
     132 
     133loader.addModule({ 
     134    name: "threadupdatepagecontroller",  
     135    type: "js", 
     136    path: "app/controllers/threadupdatepage_controller.js?" + Math.random(), 
     137    requires: ['moovc', 'thread', 'factlet', 'threadfactletsview', 'factletsearchview'], 
     138    varName: "ThreadUpdatePageController" 
     139}); 
     140 
     141loader.addModule({ 
     142    name: "geochronopagecontroller", 
     143    type: "js", 
     144    path: "app/controllers/geochronopage_controller.js?" + Math.random(), 
     145    requires: ['moovc', 'thread', 'factlet', 'mapview', 'timelineview'], 
     146    varName: "GeochronoPageController" 
    216147}); 
    217148 
     
    220151    type: "js", 
    221152    path: "app/controllers/threadpage_controller.js?" + Math.random(), 
    222     requires: ['model', 'domainobject', 'view', 'controller', 'thread', 'factlet', 'threadfactletsview', 'factletsearchview'], 
     153    requires: ['moovc', 'thread', 'factlet', 'mapview', 'timelineview', 'threadfactletsview', 'factletsearchview'], 
    223154    varName: "ThreadPageController" 
    224155}); 
    225156 
    226157loader.addModule({ 
    227     name: "geochronopagecontroller", 
     158    name: "system-under-test", 
    228159    type: "js", 
    229     path: "app/controllers/geochronopage_controller.js?" + Math.random(), 
    230     requires: ['moovc', 'model', 'domainobject', 'view', 'controller', 'thread', 'factlet', 'mapview', 'timelineview'], 
    231     varName: "GeochronoPageController" 
     160    path: "app/microfacts.js?" + Math.random(), 
     161    requires: [ 
     162        'moovc', 
     163        'threadfactletsview',  
     164        'factletdetailsview',  
     165        'threadreadpagecontroller', 
     166        'factletsearchview', 
     167        'threadupdatepagecontroller', 
     168        'mapview', 
     169        'timelineview', 
     170        'geochronopagecontroller', 
     171        'threadpagecontroller' 
     172    ], 
     173    varName: "systemUnderTest" 
    232174}); 
    233175 
     176 
  • microfacts/public/test/index.html

    r184 r200  
    4747 
    4848   <script type="text/javascript" charset="utf-8"> 
    49         loader.insert({ require: ["microfacts"] }); 
     49        loader.insert({ require: ["system-under-test"] }); 
    5050   </script> 
    5151 
    5252  <script type="text/javascript" src="spec/domain_data.js?123"></script> 
     53  <script type="text/javascript" src="spec/moovc_spec.js?123"></script> 
     54   
     55  <!-- 
     56  --> 
    5357  <script type="text/javascript" src="spec/model_spec.js?123"></script> 
    5458  <script type="text/javascript" src="spec/controller_spec.js?123"></script> 
    5559 
    56   <!-- views --> 
    57   <script type="text/javascript" src="spec/view_spec.js?123"></script> 
     60  <script type="text/javascript" src="spec/threadfactletsview_spec.js?123"></script> 
    5861  <script type="text/javascript" src="spec/factletdetailsview_spec.js?123"></script> 
    59   <script type="text/javascript" src="spec/threadfactletsview_spec.js?123"></script> 
     62  <script type="text/javascript" src="spec/threadreadpage_controller_spec.js?123"></script> 
     63   
    6064  <script type="text/javascript" src="spec/factletsearchview_spec.js?123"></script> 
     65  <script type="text/javascript" src="spec/threadupdatepage_controller_spec.js?123"></script> 
    6166 
    6267  <script type="text/javascript" src="spec/mapview_spec.js?123"></script> 
    6368  <script type="text/javascript" src="spec/timelineview_spec.js?123"></script> 
    64  
    65   <!-- (page) controllers --> 
    6669  <script type="text/javascript" src="spec/geochronopage_controller_spec.js?123"></script> 
    6770 
    68 <!-- 
    69    loader.insert({ require: ["microfacts"], onSuccess: function () { 
    70         var toload = [ 'model', 
    71             'controller', 
    72             'mapcontroller', 
    73             'timelinecontroller' 
    74             ]; 
    75         toload.each(function(val) { 
    76             $$('body').grab(new Element('script', { 
    77                 type: "text/javascript", 
    78                 src: "spec/"+val+"_spec.js?123" 
    79             })); 
    80         }); 
    81     }}); 
    82 --> 
    83  
     71  <script type="text/javascript" src="spec/threadpage_controller_spec.js?123"></script> 
    8472</head> 
    8573 
  • microfacts/public/test/spec/controller_spec.js

    r134 r200  
    1 describe("Controller", { 
     1describe("EventDelegationController", { 
    22     
    33    before_each: function () { 
    44        el = $('fixtures'); 
    55        inc = 0; 
    6         c = new Controller(el, { 
     6        c = new EventDelegationController(el, { 
    77            '#clickme eventName': function () { 
    88                inc += 1; 
  • microfacts/templates/layout.html

    r187 r200  
    2828      <script type="text/javascript" charset="utf-8"> 
    2929        var Environment = "development"; 
    30          
    3130        loader.insert({ 
    3231            require: ["${pagecontrollername()}"], 
    33  
    3432            onSuccess: function() { 
    3533                console.debug("YUILoader: All files loaded."); 
  • microfacts/templates/thread/read_geochrono.html

    r162 r200  
    1313  <head> 
    1414    <title>View - ${c.thread.title}</title> 
     15  <py:if test="c.googlemaps_apikey"> 
     16    <script src='http://maps.google.com/maps?file=api&amp;v=2&amp;key=${c.googlemaps_apikey}'></script> 
     17    <script type="text/javascript" charset="utf-8"> 
     18        var googlemaps_apikey = '${c.googlemaps_apikey}'; 
     19    </script> 
     20  </py:if>  
    1521  </head> 
    16  
    1722  <body> 
    1823    <h2>${c.thread.title}</h2> 
  • microfacts/templates/thread/read_timeline.html

    r106 r200  
    88   
    99  <xi:include href="layout.html" /> 
     10 
     11  <py:def function="pagecontrollername">threadpagecontroller</py:def> 
     12 
    1013 
    1114  <head> 
     
    4548        (${h.link_to("Edit", h.url_for(controller='thread', action='update'))}) 
    4649        </h2> 
    47       <div id="thread-timeline" style="height: 150px; border: 1px solid #aaa; margin-bottom: 20px;"></div> 
     50 <div id="timeline" style="height: 150px; border: 1px solid #aaa; margin-bottom: 20px;"></div> 
    4851       
    4952      <py:choose>   
  • microfacts/templates/thread/update.html

    r186 r200  
    99  <xi:include href="layout.html" /> 
    1010 
    11   <py:def function="pagecontrollername">threadpagecontroller</py:def> 
     11  <py:def function="pagecontrollername">threadupdatepagecontroller</py:def> 
    1212   
    1313  <head> 
  • microfacts/tests/test_models.py

    r193 r200  
    105105        out2 = thread.as_json() 
    106106        assert out2['id'] == thread.id 
    107         assert out2['factlets'][0] == fct.id 
     107        assert fct.id in out2['factlets'], "List of ids: %s" % out2['factlets'] 
    108108 
    109109    def test_ordered_list(self):