omf_web 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
  }