/
mount.js
115 lines (97 loc) · 3.16 KB
/
mount.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
'use strict';
var unescape = require('./unescape');
var state = require('./state');
var router = require('./router');
var activator = require('./activator');
var caching = require('./caching');
var componentCache = require('./componentCache');
var fetcher = require('./fetcher');
var versioning = require('../versioning');
var document = require('./global/document');
var location = require('./global/location');
var g = global;
var mounted;
var booted;
function orEmpty (value) {
return value || '';
}
function mount (container, wiring, options) {
var o = options || {};
if (mounted) {
throw new Error('Taunus already mounted!');
}
if (!container || !container.tagName) { // naïve is enough
throw new Error('You must define an application root container!');
}
if (!o.bootstrap) { o.bootstrap = 'auto'; }
mounted = true;
global.DEBUG && global.DEBUG('[mount] mountpoint invoked using "%s" strategy', o.bootstrap);
state.container = container;
state.controllers = wiring.controllers;
state.templates = wiring.templates;
state.routes = wiring.routes;
state.deferrals = wiring.deferrals || [];
state.prefetch = !!o.prefetch;
state.version = versioning.get(o.version || '1');
router.setup(wiring.routes);
var url = location.pathname;
var query = orEmpty(location.search) + orEmpty(location.hash);
var route = router(url + query);
caching.setup(o.cache, route);
caching.ready(kickstart);
componentCache.refill();
function kickstart () {
if (o.bootstrap === 'auto') {
autoboot();
} else if (o.bootstrap === 'inline') {
inlineboot();
} else if (o.bootstrap === 'manual') {
manualboot();
} else {
throw new Error(o.bootstrap + ' is not a valid bootstrap mode!');
}
}
function autoboot () {
fetcher(route, { element: container, source: 'boot' }, fetched);
}
function fetched (err, data) {
if (err) {
throw new Error('Fetching JSON data model failed at mountpoint.');
}
boot(data);
}
function inlineboot () {
var id = container.getAttribute('data-taunus');
var script = document.getElementById(id);
var data = JSON.parse(unescape(script.innerText || script.textContent));
boot(data);
}
function manualboot () {
if (typeof g.taunusReady === 'function') {
g.taunusReady = boot; // not yet an object? turn it into the boot method
} else if (g.taunusReady && typeof g.taunusReady === 'object') {
boot(g.taunusReady); // already an object? boot with that as the data object
} else {
throw new Error('Did you forget to add the taunusReady global?');
}
}
function boot (data) {
if (booted) { // sanity
return;
}
global.DEBUG && global.DEBUG('[mount] mountpoint booted with data', data);
if (!data) {
throw new Error('Taunus data is required! Boot failed');
}
if (!data.version) {
throw new Error('Version data is missing! Boot failed');
}
if (!data.model || typeof data.model !== 'object') {
throw new Error('Taunus model must be an object! Boot failed');
}
booted = true;
caching.persist(route, state.container, data);
activator.start(data);
}
}
module.exports = mount;