omf_web 1.0.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. data/bin/omf_web_server +18 -0
  2. data/example/bridge/README.md +7 -0
  3. data/example/bridge/data_sources/sensor-sqlite.rb +15 -15
  4. data/example/bridge/htdocs/graph/js/bridge.js +35 -45
  5. data/example/bridge/htdocs/graph/js/event_line_chart.js +20 -18
  6. data/example/bridge/htdocs/graph/js/event_table.js +26 -28
  7. data/example/bridge/viz_server.rb +5 -9
  8. data/example/demo/demo_viz_server.rb +2 -2
  9. data/example/demo/widgets/linked_graphs_tab.yaml +9 -32
  10. data/example/openflow-gec15/code_tab.yaml +7 -12
  11. data/example/openflow-gec15/dashboard_tab.yaml +11 -12
  12. data/example/openflow-gec15/exp_source.rb +26 -26
  13. data/example/openflow-gec15/of_viz_server.rb +7 -7
  14. data/example/simple/simple.yaml +2 -1
  15. data/example/simple/simple_dynamic.yaml +1 -1
  16. data/example/web_rtc/web_rtc.yaml +54 -0
  17. data/example/web_rtc/webrtc-exp_1381786573.sq3 +0 -0
  18. data/lib/omf-web/config.ru +1 -1
  19. data/lib/omf-web/content/content_proxy.rb +2 -2
  20. data/lib/omf-web/content/file_repository.rb +11 -53
  21. data/lib/omf-web/content/git_repository.rb +1 -1
  22. data/lib/omf-web/content/irods_repository.rb +1 -1
  23. data/lib/omf-web/content/repository.rb +5 -3
  24. data/lib/omf-web/content/static_repository.rb +25 -11
  25. data/lib/omf-web/data_source_proxy.rb +3 -3
  26. data/lib/omf-web/rack/content_handler.rb +2 -2
  27. data/lib/omf-web/rack/session_authenticator.rb +3 -3
  28. data/lib/omf-web/rack/tab_mapper.rb +2 -2
  29. data/lib/omf-web/rack/update_handler.rb +2 -2
  30. data/lib/omf-web/rack/websocket_handler.rb +3 -3
  31. data/lib/omf-web/rack/widget_mapper.rb +2 -2
  32. data/lib/omf-web/session_store.rb +2 -2
  33. data/lib/omf-web/theme/abstract_page.rb +15 -24
  34. data/lib/omf-web/theme/bright/code_renderer.rb +24 -30
  35. data/lib/omf-web/theme/bright/data_renderer.rb +7 -5
  36. data/lib/omf-web/theme/bright/page.rb +2 -1
  37. data/lib/omf-web/theme/bright/widget_chrome.rb +16 -14
  38. data/lib/omf-web/theme.rb +1 -1
  39. data/lib/omf-web/thin/logging.rb +18 -13
  40. data/lib/omf-web/thin/runner.rb +2 -2
  41. data/lib/omf-web/thin/server.rb +105 -27
  42. data/lib/omf-web/version.rb +1 -1
  43. data/lib/omf-web/widget/abstract_widget.rb +3 -3
  44. data/lib/omf-web/widget/data_widget.rb +1 -0
  45. data/lib/omf-web/widget/text/maruku.rb +1 -1
  46. data/lib/omf-web/widget.rb +22 -22
  47. data/lib/omf_web.rb +1 -1
  48. data/omf_web.gemspec +18 -15
  49. data/share/htdocs/graph/js/abstract_chart.js +69 -68
  50. data/share/htdocs/graph/js/abstract_nv_chart.js +35 -33
  51. data/share/htdocs/graph/js/abstract_widget.js +61 -62
  52. data/share/htdocs/graph/js/axis.js +30 -25
  53. data/share/htdocs/graph/js/barchart_brush.js +23 -21
  54. data/share/htdocs/graph/js/code_mirror.js +35 -33
  55. data/share/htdocs/graph/js/discrete_bar_chart.js +27 -30
  56. data/share/htdocs/graph/js/histogram2.js +37 -47
  57. data/share/htdocs/graph/js/line_chart3.js +36 -30
  58. data/share/htdocs/graph/js/line_chart_with_focus.js +10 -9
  59. data/share/htdocs/graph/js/multi_barchart.js +33 -30
  60. data/share/htdocs/graph/js/network2.js +98 -97
  61. data/share/htdocs/graph/js/pie_chart2.js +25 -23
  62. data/share/htdocs/graph/js/scatter_plot.js +38 -36
  63. data/share/htdocs/graph/js/table2.js +60 -54
  64. data/share/htdocs/js/app.js +43 -0
  65. data/share/htdocs/js/{data_source2.js → data_source3.js} +44 -73
  66. data/share/htdocs/js/data_source_repo.js +42 -0
  67. data/share/htdocs/require/nv_d3.js +2 -0
  68. data/share/htdocs/theme/abstract/abstract.js +4 -4
  69. data/share/htdocs/vendor/VERSION_MAP.yaml +2 -0
  70. data/share/htdocs/vendor/require-2.1.8/require.js +2053 -0
  71. data/share/htdocs/vendor/require-2.1.8/require.min.js +36 -0
  72. data/share/htdocs/vendor/require-css-0.0.7/.gitignore +1 -0
  73. data/share/htdocs/vendor/require-css-0.0.7/LICENSE +10 -0
  74. data/share/htdocs/vendor/require-css-0.0.7/README.md +231 -0
  75. data/share/htdocs/vendor/require-css-0.0.7/bower.json +5 -0
  76. data/share/htdocs/vendor/require-css-0.0.7/css-builder.js +251 -0
  77. data/share/htdocs/vendor/require-css-0.0.7/css.js +436 -0
  78. data/share/htdocs/vendor/require-css-0.0.7/normalize.js +138 -0
  79. data/share/htdocs/vendor/require-css-0.0.7/package.json +5 -0
  80. data/share/htdocs/vendor/spin/jquery.spin.js +6 -4
  81. metadata +100 -74
  82. checksums.yaml +0 -7
  83. data/bin/omf_web_demo +0 -3
  84. data/bin/omf_web_demo.sh +0 -7
  85. data/bin/omf_web_server.rb +0 -157
  86. data/lib/omf_common/lobject.rb +0 -187
  87. data/lib/omf_common/log4r_outputter.rb +0 -69
  88. data/sample.sq3 +0 -0
  89. data/share/htdocs/js/data_source.js +0 -173
  90. data/share/htdocs/js/require3.js +0 -292
@@ -0,0 +1,436 @@
1
+ /*
2
+ * Require-CSS RequireJS css! loader plugin
3
+ * Guy Bedford 2013
4
+ * MIT
5
+ */
6
+
7
+ /*
8
+ *
9
+ * Usage:
10
+ * require(['css!./mycssFile']);
11
+ *
12
+ * NB leave out the '.css' extension.
13
+ *
14
+ * - Fully supports cross origin CSS loading
15
+ * - Works with builds
16
+ *
17
+ * Tested and working in (up to latest versions as of March 2013):
18
+ * Android
19
+ * iOS 6
20
+ * IE 6 - 10
21
+ * Chome 3 - 26
22
+ * Firefox 3.5 - 19
23
+ * Opera 10 - 12
24
+ *
25
+ * browserling.com used for virtual testing environment
26
+ *
27
+ * Credit to B Cavalier & J Hann for the elegant IE 6 - 9 hack.
28
+ *
29
+ * Sources that helped along the way:
30
+ * - https://developer.mozilla.org/en-US/docs/Browser_detection_using_the_user_agent
31
+ * - http://www.phpied.com/when-is-a-stylesheet-really-loaded/
32
+ * - https://github.com/cujojs/curl/blob/master/src/curl/plugin/css.js
33
+ *
34
+ */
35
+
36
+ define(['./normalize'], function(normalize) {
37
+ function indexOf(a, e) { for (var i=0, l=a.length; i < l; i++) if (a[i] === e) return i; return -1 }
38
+
39
+ if (typeof window == 'undefined')
40
+ return { load: function(n, r, load){ load() } };
41
+
42
+ // set to true to enable test prompts for device testing
43
+ var testing = false;
44
+
45
+ var head = document.getElementsByTagName('head')[0];
46
+
47
+ var engine = window.navigator.userAgent.match(/Trident\/([^ ;]*)|AppleWebKit\/([^ ;]*)|Opera\/([^ ;]*)|rv\:([^ ;]*)(.*?)Gecko\/([^ ;]*)|MSIE\s([^ ;]*)/);
48
+ var hackLinks = false;
49
+
50
+ if (!engine) {}
51
+ else if (engine[1] || engine[7]) {
52
+ hackLinks = parseInt(engine[1]) < 6 || parseInt(engine[7]) <= 9;
53
+ engine = 'trident';
54
+ }
55
+ else if (engine[2]) {
56
+ // unfortunately style querying still doesnt work with onload callback in webkit
57
+ hackLinks = true;
58
+ engine = 'webkit';
59
+ }
60
+ else if (engine[3]) {
61
+ // engine = 'opera';
62
+ }
63
+ else if (engine[4]) {
64
+ hackLinks = parseInt(engine[4]) < 18;
65
+ engine = 'gecko';
66
+ }
67
+ else if (testing)
68
+ alert('Engine detection failed');
69
+
70
+ //main api object
71
+ var cssAPI = {};
72
+
73
+ var absUrlRegEx = /^\/|([^\:\/]*:)/;
74
+
75
+ cssAPI.pluginBuilder = './css-builder';
76
+
77
+ // used by layer builds to register their css buffers
78
+
79
+ // the current layer buffer items (from addBuffer)
80
+ var curBuffer = [];
81
+
82
+ // the callbacks for buffer loads
83
+ var onBufferLoad = {};
84
+
85
+ // the full list of resources in the buffer
86
+ var bufferResources = [];
87
+
88
+ cssAPI.addBuffer = function(resourceId) {
89
+ // just in case layer scripts are included twice, also check
90
+ // against the previous buffers
91
+ if (indexOf(curBuffer, resourceId) != -1)
92
+ return;
93
+ if (indexOf(bufferResources, resourceId) != -1)
94
+ return;
95
+ curBuffer.push(resourceId);
96
+ bufferResources.push(resourceId);
97
+ }
98
+ cssAPI.setBuffer = function(css, isLess) {
99
+ var pathname = window.location.pathname.split('/');
100
+ pathname.pop();
101
+ pathname = pathname.join('/') + '/';
102
+
103
+ var baseParts = require.toUrl('base_url').split('/');
104
+ baseParts.pop();
105
+ var baseUrl = baseParts.join('/') + '/';
106
+ baseUrl = normalize.convertURIBase(baseUrl, pathname, '/');
107
+ if (!baseUrl.match(absUrlRegEx))
108
+ baseUrl = '/' + baseUrl;
109
+ if (baseUrl.substr(baseUrl.length - 1, 1) != '/')
110
+ baseUrl = baseUrl + '/';
111
+
112
+ cssAPI.inject(normalize(css, baseUrl, pathname));
113
+
114
+ // set up attach callback if registered
115
+ // clear the current buffer for the next layer
116
+ // (just the less or css part as we have two buffers in one effectively)
117
+ for (var i = 0; i < curBuffer.length; i++) {
118
+ // find the resources in the less or css buffer dependening which one this is
119
+ if ((isLess && curBuffer[i].substr(curBuffer[i].length - 5, 5) == '.less') ||
120
+ (!isLess && curBuffer[i].substr(curBuffer[i].length - 4, 4) == '.css')) {
121
+ (function(resourceId) {
122
+ // mark that the onBufferLoad is about to be called (set to true if not already a callback function)
123
+ onBufferLoad[resourceId] = onBufferLoad[resourceId] || true;
124
+
125
+ // set a short timeout (as injection isn't instant in Chrome), then call the load
126
+ setTimeout(function() {
127
+ if (typeof onBufferLoad[resourceId] == 'function')
128
+ onBufferLoad[resourceId]();
129
+ // remove from onBufferLoad to indicate loaded
130
+ delete onBufferLoad[resourceId];
131
+ }, 7);
132
+ })(curBuffer[i]);
133
+
134
+ // remove the current resource from the buffer
135
+ curBuffer.splice(i--, 1);
136
+ }
137
+ }
138
+ }
139
+ cssAPI.attachBuffer = function(resourceId, load) {
140
+ // attach can happen during buffer collecting, or between injection and callback
141
+ // we assume it is not possible to attach multiple callbacks
142
+ // requirejs plugin load function ensures this by queueing duplicate calls
143
+
144
+ // check if the resourceId is in the current buffer
145
+ for (var i = 0; i < curBuffer.length; i++)
146
+ if (curBuffer[i] == resourceId) {
147
+ onBufferLoad[resourceId] = load;
148
+ return true;
149
+ }
150
+
151
+ // check if the resourceId is waiting for injection callback
152
+ // (onBufferLoad === true is a shortcut indicator for this)
153
+ if (onBufferLoad[resourceId] === true) {
154
+ onBufferLoad[resourceId] = load;
155
+ return true;
156
+ }
157
+
158
+ // if it's in the full buffer list and not either of the above, its loaded already
159
+ if (indexOf(bufferResources, resourceId) != -1) {
160
+ load();
161
+ return true;
162
+ }
163
+ }
164
+
165
+ var webkitLoadCheck = function(link, callback) {
166
+ setTimeout(function() {
167
+ for (var i = 0; i < document.styleSheets.length; i++) {
168
+ var sheet = document.styleSheets[i];
169
+ if (sheet.href == link.href)
170
+ return callback();
171
+ }
172
+ webkitLoadCheck(link, callback);
173
+ }, 10);
174
+ }
175
+
176
+ var mozillaLoadCheck = function(style, callback) {
177
+ setTimeout(function() {
178
+ try {
179
+ style.sheet.cssRules;
180
+ return callback();
181
+ } catch (e){}
182
+ mozillaLoadCheck(style, callback);
183
+ }, 10);
184
+ }
185
+
186
+ // ie link detection, as adapted from https://github.com/cujojs/curl/blob/master/src/curl/plugin/css.js
187
+ if (engine == 'trident' && hackLinks) {
188
+ var ieStyles = [],
189
+ ieQueue = [],
190
+ ieStyleCnt = 0;
191
+ var ieLoad = function(url, callback) {
192
+ var style;
193
+ ieQueue.push({
194
+ url: url,
195
+ cb: callback
196
+ });
197
+ style = ieStyles.shift();
198
+ if (!style && ieStyleCnt++ < 31) {
199
+ style = document.createElement('style');
200
+ head.appendChild(style);
201
+ }
202
+ if (style)
203
+ ieLoadNextImport(style);
204
+ }
205
+ var ieLoadNextImport = function(style) {
206
+ var curImport = ieQueue.shift();
207
+ if (!curImport) {
208
+ style.onload = noop;
209
+ ieStyles.push(style);
210
+ return;
211
+ }
212
+ style.onload = function() {
213
+ curImport.cb(curImport.ss);
214
+ ieLoadNextImport(style);
215
+ };
216
+ var curSheet = style.styleSheet;
217
+ curImport.ss = curSheet.imports[curSheet.addImport(curImport.url)];
218
+ }
219
+ }
220
+
221
+ // uses the <link> load method
222
+ var createLink = function(url) {
223
+ var link = document.createElement('link');
224
+ link.type = 'text/css';
225
+ link.rel = 'stylesheet';
226
+ link.href = url;
227
+ return link;
228
+ }
229
+
230
+ var noop = function(){}
231
+
232
+ cssAPI.linkLoad = function(url, callback) {
233
+ var timeout = setTimeout(function() {
234
+ if (testing) alert('timeout');
235
+ callback();
236
+ }, waitSeconds * 1000 - 100);
237
+ var _callback = function() {
238
+ clearTimeout(timeout);
239
+ if (link)
240
+ link.onload = noop;
241
+ // for style querying, a short delay still seems necessary
242
+ setTimeout(callback, 7);
243
+ }
244
+ if (!hackLinks) {
245
+ var link = createLink(url);
246
+ link.onload = _callback;
247
+ head.appendChild(link);
248
+ }
249
+ // hacks
250
+ else {
251
+ if (engine == 'webkit') {
252
+ var link = createLink(url);
253
+ webkitLoadCheck(link, _callback);
254
+ head.appendChild(link);
255
+ }
256
+ else if (engine == 'gecko') {
257
+ var style = document.createElement('style');
258
+ style.textContent = '@import "' + url + '"';
259
+ mozillaLoadCheck(style, _callback);
260
+ head.appendChild(style);
261
+ }
262
+ else if (engine == 'trident')
263
+ ieLoad(url, _callback);
264
+ }
265
+ }
266
+
267
+ /* injection api */
268
+ var progIds = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'];
269
+ var fileCache = {};
270
+ var get = function(url, callback, errback) {
271
+ if (fileCache[url]) {
272
+ callback(fileCache[url]);
273
+ return;
274
+ }
275
+
276
+ var xhr, i, progId;
277
+ if (typeof XMLHttpRequest !== 'undefined')
278
+ xhr = new XMLHttpRequest();
279
+ else if (typeof ActiveXObject !== 'undefined')
280
+ for (i = 0; i < 3; i += 1) {
281
+ progId = progIds[i];
282
+ try {
283
+ xhr = new ActiveXObject(progId);
284
+ }
285
+ catch (e) {}
286
+
287
+ if (xhr) {
288
+ progIds = [progId]; // so faster next time
289
+ break;
290
+ }
291
+ }
292
+
293
+ xhr.open('GET', url, requirejs.inlineRequire ? false : true);
294
+
295
+ xhr.onreadystatechange = function (evt) {
296
+ var status, err;
297
+ //Do not explicitly handle errors, those should be
298
+ //visible via console output in the browser.
299
+ if (xhr.readyState === 4) {
300
+ status = xhr.status;
301
+ if (status > 399 && status < 600) {
302
+ //An http 4xx or 5xx error. Signal an error.
303
+ err = new Error(url + ' HTTP status: ' + status);
304
+ err.xhr = xhr;
305
+ errback(err);
306
+ }
307
+ else {
308
+ fileCache[url] = xhr.responseText;
309
+ callback(xhr.responseText);
310
+ }
311
+ }
312
+ };
313
+
314
+ xhr.send(null);
315
+ }
316
+ //uses the <style> load method
317
+ var styleCnt = 0;
318
+ var curStyle;
319
+ cssAPI.inject = function(css) {
320
+ if (styleCnt < 31) {
321
+ curStyle = document.createElement('style');
322
+ curStyle.type = 'text/css';
323
+ head.appendChild(curStyle);
324
+ styleCnt++;
325
+ }
326
+ if (curStyle.styleSheet)
327
+ curStyle.styleSheet.cssText += css;
328
+ else
329
+ curStyle.appendChild(document.createTextNode(css));
330
+ }
331
+
332
+ // NB add @media query support for media imports
333
+ var importRegEx = /@import\s*(url)?\s*(('([^']*)'|"([^"]*)")|\(('([^']*)'|"([^"]*)"|([^\)]*))\))\s*;?/g;
334
+
335
+ var pathname = window.location.pathname.split('/');
336
+ pathname.pop();
337
+ pathname = pathname.join('/') + '/';
338
+
339
+ var loadCSS = function(fileUrl, callback, errback) {
340
+
341
+ //make file url absolute
342
+ if (!fileUrl.match(absUrlRegEx))
343
+ fileUrl = '/' + normalize.convertURIBase(fileUrl, pathname, '/');
344
+
345
+ get(fileUrl, function(css) {
346
+
347
+ // normalize the css (except import statements)
348
+ css = normalize(css, fileUrl, pathname);
349
+
350
+ // detect all import statements in the css and normalize
351
+ var importUrls = [];
352
+ var importIndex = [];
353
+ var importLength = [];
354
+ var match;
355
+ while (match = importRegEx.exec(css)) {
356
+ var importUrl = match[4] || match[5] || match[7] || match[8] || match[9];
357
+
358
+ importUrls.push(importUrl);
359
+ importIndex.push(importRegEx.lastIndex - match[0].length);
360
+ importLength.push(match[0].length);
361
+ }
362
+
363
+ // load the import stylesheets and substitute into the css
364
+ var completeCnt = 0;
365
+ for (var i = 0; i < importUrls.length; i++)
366
+ (function(i) {
367
+ loadCSS(importUrls[i], function(importCSS) {
368
+ css = css.substr(0, importIndex[i]) + importCSS + css.substr(importIndex[i] + importLength[i]);
369
+ var lenDiff = importCSS.length - importLength[i];
370
+ for (var j = i + 1; j < importUrls.length; j++)
371
+ importIndex[j] += lenDiff;
372
+ completeCnt++;
373
+ if (completeCnt == importUrls.length) {
374
+ callback(css);
375
+ }
376
+ }, errback);
377
+ })(i);
378
+
379
+ if (importUrls.length == 0)
380
+ callback(css);
381
+ }, errback);
382
+ }
383
+
384
+
385
+ cssAPI.normalize = function(name, normalize) {
386
+ if (name.substr(name.length - 4, 4) == '.css')
387
+ name = name.substr(0, name.length - 4);
388
+
389
+ return normalize(name);
390
+ }
391
+
392
+ var waitSeconds;
393
+ var alerted = false;
394
+ cssAPI.load = function(cssId, req, load, config, parse) {
395
+
396
+ waitSeconds = waitSeconds || config.waitSeconds || 7;
397
+
398
+ var resourceId = cssId + (!parse ? '.css' : '.less');
399
+
400
+ // attach the load function to a buffer if there is one in registration
401
+ // if not, we do a full injection load
402
+ if (cssAPI.attachBuffer(resourceId, load))
403
+ return;
404
+
405
+ var fileUrl = req.toUrl(resourceId);
406
+
407
+ if (!alerted && testing) {
408
+ alert(hackLinks ? 'hacking links' : 'not hacking');
409
+ alerted = true;
410
+ }
411
+
412
+ if (!parse) {
413
+ cssAPI.linkLoad(fileUrl, load);
414
+ }
415
+ else {
416
+ loadCSS(fileUrl, function(css) {
417
+ // run parsing after normalization - since less is a CSS subset this works fine
418
+ if (parse)
419
+ css = parse(css, function(css) {
420
+ cssAPI.inject(css);
421
+ setTimeout(load, 7);
422
+ });
423
+ });
424
+ }
425
+ }
426
+
427
+ if (testing)
428
+ cssAPI.inspect = function() {
429
+ if (stylesheet.styleSheet)
430
+ return stylesheet.styleSheet.cssText;
431
+ else if (stylesheet.innerHTML)
432
+ return stylesheet.innerHTML;
433
+ }
434
+
435
+ return cssAPI;
436
+ });
@@ -0,0 +1,138 @@
1
+ /*
2
+ * css.normalize.js
3
+ *
4
+ * CSS Normalization
5
+ *
6
+ * CSS paths are normalized based on an optional basePath and the RequireJS config
7
+ *
8
+ * Usage:
9
+ * normalize(css, fromBasePath, toBasePath);
10
+ *
11
+ * css: the stylesheet content to normalize
12
+ * fromBasePath: the absolute base path of the css relative to any root (but without ../ backtracking)
13
+ * toBasePath: the absolute new base path of the css relative to the same root
14
+ *
15
+ * Absolute dependencies are left untouched.
16
+ *
17
+ * Urls in the CSS are picked up by regular expressions.
18
+ * These will catch all statements of the form:
19
+ *
20
+ * url(*)
21
+ * url('*')
22
+ * url("*")
23
+ *
24
+ * @import '*'
25
+ * @import "*"
26
+ *
27
+ * (and so also @import url(*) variations)
28
+ *
29
+ * For urls needing normalization
30
+ *
31
+ */
32
+
33
+ define(['require', 'module'], function(require, module) {
34
+
35
+ // regular expression for removing double slashes
36
+ // eg http://www.example.com//my///url/here -> http://www.example.com/my/url/here
37
+ var slashes = /([^:])\/+/g
38
+ var removeDoubleSlashes = function(uri) {
39
+ return uri.replace(slashes, '$1/');
40
+ }
41
+
42
+ // given a relative URI, and two absolute base URIs, convert it from one base to another
43
+ var protocolRegEx = /[^\:\/]*:\/\/([^\/])*/
44
+ function convertURIBase(uri, fromBase, toBase) {
45
+ if(uri.indexOf("data:") === 0)
46
+ return uri;
47
+ uri = removeDoubleSlashes(uri);
48
+ // absolute urls are left in tact
49
+ if (uri.match(/^\//) || uri.match(protocolRegEx))
50
+ return uri;
51
+ // if toBase specifies a protocol path, ensure this is the same protocol as fromBase, if not
52
+ // use absolute path at fromBase
53
+ var toBaseProtocol = toBase.match(protocolRegEx);
54
+ var fromBaseProtocol = fromBase.match(protocolRegEx);
55
+ if (fromBaseProtocol && (!toBaseProtocol || toBaseProtocol[1] != fromBaseProtocol[1] || toBaseProtocol[2] != fromBaseProtocol[2]))
56
+ return absoluteURI(uri, fromBase);
57
+
58
+ else {
59
+ return relativeURI(absoluteURI(uri, fromBase), toBase);
60
+ }
61
+ };
62
+
63
+ // given a relative URI, calculate the absolute URI
64
+ function absoluteURI(uri, base) {
65
+ if (uri.substr(0, 2) == './')
66
+ uri = uri.substr(2);
67
+
68
+ var baseParts = base.split('/');
69
+ var uriParts = uri.split('/');
70
+
71
+ baseParts.pop();
72
+
73
+ while (curPart = uriParts.shift())
74
+ if (curPart == '..')
75
+ baseParts.pop();
76
+ else
77
+ baseParts.push(curPart);
78
+
79
+ return baseParts.join('/');
80
+ };
81
+
82
+
83
+ // given an absolute URI, calculate the relative URI
84
+ function relativeURI(uri, base) {
85
+
86
+ // reduce base and uri strings to just their difference string
87
+ var baseParts = base.split('/');
88
+ baseParts.pop();
89
+ base = baseParts.join('/') + '/';
90
+ i = 0;
91
+ while (base.substr(i, 1) == uri.substr(i, 1))
92
+ i++;
93
+ while (base.substr(i, 1) != '/')
94
+ i--;
95
+ base = base.substr(i + 1);
96
+ uri = uri.substr(i + 1);
97
+
98
+ // each base folder difference is thus a backtrack
99
+ baseParts = base.split('/');
100
+ var uriParts = uri.split('/');
101
+ out = '';
102
+ while (baseParts.shift())
103
+ out += '../';
104
+
105
+ // finally add uri parts
106
+ while (curPart = uriParts.shift())
107
+ out += curPart + '/';
108
+
109
+ return out.substr(0, out.length - 1);
110
+ };
111
+
112
+ var normalizeCSS = function(source, fromBase, toBase, cssBase) {
113
+
114
+ fromBase = removeDoubleSlashes(fromBase);
115
+ toBase = removeDoubleSlashes(toBase);
116
+
117
+ var urlRegEx = /@import\s*("([^"]*)"|'([^']*)')|url\s*\(\s*(\s*"([^"]*)"|'([^']*)'|[^\)]*\s*)\s*\)/ig;
118
+ var result, url, source;
119
+
120
+ while (result = urlRegEx.exec(source)) {
121
+ url = result[3] || result[2] || result[5] || result[6] || result[4];
122
+ var newUrl;
123
+ if (cssBase && url.substr(0, 1) == '/')
124
+ newUrl = cssBase + url;
125
+ else
126
+ newUrl = convertURIBase(url, fromBase, toBase);
127
+ var quoteLen = result[5] || result[6] ? 1 : 0;
128
+ source = source.substr(0, urlRegEx.lastIndex - url.length - quoteLen - 1) + newUrl + source.substr(urlRegEx.lastIndex - quoteLen - 1);
129
+ urlRegEx.lastIndex = urlRegEx.lastIndex + (newUrl.length - url.length);
130
+ }
131
+
132
+ return source;
133
+ };
134
+
135
+ normalizeCSS.convertURIBase = convertURIBase;
136
+
137
+ return normalizeCSS;
138
+ });
@@ -0,0 +1,5 @@
1
+ {
2
+ "volo": {
3
+ "type": "directory"
4
+ }
5
+ }
@@ -20,7 +20,7 @@
20
20
  // left: 'auto' // Left position relative to parent in px
21
21
  // };
22
22
 
23
- function _jquery_spin_() {
23
+ function _jquery_spin_(Spinner) {
24
24
  $.fn.spin = function(opts) {
25
25
  this.each(function() {
26
26
  var $this = $(this),
@@ -38,9 +38,11 @@ function _jquery_spin_() {
38
38
  };
39
39
  }
40
40
 
41
- if (L != undefined) {
42
- L.provide('jquery.spin', ['/resource/vendor/spin/spin.min.js'], _jquery_spin_);
41
+ if (typeof(define) != undefined) {
42
+ define(['vendor/spin/spin.min'], function(Spinner) {
43
+ _jquery_spin_(Spinner)
44
+ });
43
45
  } else {
44
46
  // This assumes that /resource/vendor/spin/spin.min.js has already been loaded
45
- _jquery_spin_();
47
+ _jquery_spin_(Spinner);
46
48
  }