radiant-fabulator_exhibit-extension 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,457 @@
1
+ /*
2
+ * (c) Copyright Texas A&M University 2010. All rights reserved.
3
+ *
4
+ * Portions of this code are copied from The SIMILE Project:
5
+ * (c) Copyright The SIMILE Project 2006. All rights reserved.
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted provided that the following conditions
9
+ * are met:
10
+ *
11
+ * 1. Redistributions of source code must retain the above copyright
12
+ * notice, this list of conditions and the following disclaimer.
13
+ *
14
+ * 2. Redistributions in binary form must reproduce the above copyright
15
+ * notice, this list of conditions and the following disclaimer in the
16
+ * documentation and/or other materials provided with the distribution.
17
+ *
18
+ * 3. The name of the author may not be used to endorse or promote products
19
+ * derived from this software without specific prior written permission.
20
+ *
21
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ *
32
+ */
33
+
34
+ (function($, Exhibit) {
35
+
36
+ Exhibit.Presentations = function(container, options) {
37
+ var that = fluid.initView("Fabulator.Exhibit.Presentations", container, options),
38
+ items = new Array(),
39
+ item_id_to_pos = { },
40
+ presentationStyle,
41
+ viewClass, viewClassObj, tab_html;
42
+
43
+ var calculatePositions = function() {
44
+ /* we have glue between panels */
45
+ /* vertically, all glues need to equalize. same horizontally */
46
+ /* we want to minimize the tension in the system */
47
+ /* it's a system of equations that we're solving :-/ */
48
+
49
+ /* n scales d, so x := d / n
50
+ T = a / x - b * x
51
+ */
52
+ var T = function(a, b, d, n) { return n*a/d - b*d/n; };
53
+
54
+ /* the square of the best fit for a particular piece of glue */
55
+ var sweetSpot = function(a, b, n) { return n * n * a / b; };
56
+
57
+ /* the direction a spot should move for a glue */
58
+ var velocity = function(a, b, d, n) {
59
+ sweetSpot(a, b, n) - d*d;
60
+ }
61
+
62
+ var horizontal_distance = function(a, b) { return b.x - a.x; };
63
+ var vertical_distance = function(a, b) { return b.y - a.y; };
64
+
65
+ /* we want to figure out an ordering of items */
66
+ /* things glued to the left frame are first horizontally
67
+ things glued to the top frame are first vertically */
68
+ var horiz_graph = new Array();
69
+ var vert_graph = new Array();
70
+
71
+ horiz_graph[0] = new Array();
72
+ vert_graph[0] = new Array();
73
+
74
+ for(i = 0, n = items.length; i < n; i++) {
75
+ var dir, item_vert, item_horiz;
76
+
77
+ horiz_graph[i+1] = new Array();
78
+ vert_graph[i+1] = new Array();
79
+
80
+ dir = items[i].left;
81
+ if( typeof(dir) != "undefined" ) {
82
+ var j;
83
+ if( dir.id == "frame" ) {
84
+ j = 0;
85
+ }
86
+ else {
87
+ j = item_id_to_pos[dir.id];
88
+ }
89
+ horiz_graph[j][i] = { a: dir.a, b: dir.b };
90
+ }
91
+
92
+ dir = items[i].right;
93
+ if( typeof(dir) != "undefined" ) {
94
+ var j;
95
+ if( dir.id == "frame" ) {
96
+ j = n;
97
+ }
98
+ else {
99
+ j = item_id_to_pos[dir.id];
100
+ }
101
+ horiz_graph[i+1][j] = { a: dir.a, b: dir.b };
102
+ }
103
+
104
+ dir = items[i].top;
105
+ if( typeof(dir) != "undefined" ) {
106
+ var j;
107
+ if( dir.id == "frame" ) {
108
+ j = 0;
109
+ }
110
+ else {
111
+ j = item_id_to_pos[dir.id];
112
+ }
113
+ vert_graph[j][i] = { a: dir.a, b: dir.b };
114
+ }
115
+
116
+ dir = items[i].bottom;
117
+ if( typeof(dir) != "undefined" ) {
118
+ var j;
119
+ if( dir.id == "frame" ) {
120
+ j = n;
121
+ }
122
+ else {
123
+ j = item_id_to_pos[dir.id];
124
+ }
125
+ vert_graph[i+1][j] = { a: dir.a, b: dir.b };
126
+ }
127
+
128
+ }
129
+ };
130
+
131
+ options = that.options;
132
+
133
+ that.views = new Array();
134
+
135
+ if( $(container).attr('ex:arrangement') == 'flat' ) {
136
+ presentationStyle = 'flat';
137
+ }
138
+ else {
139
+ presentationStyle = 'tabbed';
140
+ }
141
+
142
+ that.eventModelChange = function(model) {
143
+ $(that.views).each(function(idx, view) {
144
+ view.eventModelChange(model);
145
+ });
146
+ };
147
+
148
+ $(container).children().each(function(idx, el) {
149
+ if($(el).attr('ex:role') == 'view') {
150
+ viewClass = $(el).attr('ex:viewClass') || 'Tile';
151
+ viewClassObj = Fabulator.Exhibit.Presentations[viewClass];
152
+
153
+ if(typeof(viewClassObj) != "undefined") {
154
+ items.push(el);
155
+ item_id_to_pos[$(el).attr('id')] = items.length - 1;
156
+ that.views.push(viewClassObj(el, { viewPanel: options.viewPanel }));
157
+ }
158
+ }
159
+ });
160
+
161
+ /* if multiple presentations, use tabs */
162
+
163
+ if(presentationStyle == 'tabbed' && items.length > 1) {
164
+ tab_html = "<ul>";
165
+
166
+ $(items).each(function(idx, t) {
167
+ tab_html = tab_html +
168
+ "<li><a href='#" + $(t).attr('id') + "'>" +
169
+ $(t).attr('ex:viewLabel') + "</a></li>"
170
+ });
171
+ tab_html = tab_html + "</ul>";
172
+ $(tab_html).prependTo($(container));
173
+
174
+ $(container).tabs();
175
+ }
176
+ else if(presentationStyle == 'flat') {
177
+ }
178
+ else {
179
+ $(container).addClass("ui-dialog-content ui-widget-content");
180
+ /* $(container).attr("style", "min-height: 400px; width: *;"); */
181
+ }
182
+
183
+ return that;
184
+ };
185
+
186
+ Exhibit.Presentations.Container = function(container, options) {
187
+ var that = fluid.initView("Fabulator.Exhibit.Presentations", container, options),
188
+ items = new Array(),
189
+ presentationStyle,
190
+ viewClass, viewClassObj, tab_html;
191
+ };
192
+
193
+ Exhibit.Presentations.Tile = function(container, options) {
194
+ var that = fluid.initView("Fabulator.Exhibit.Presentations.Tile", container, options),
195
+ lenses = new Array(),
196
+ l;
197
+
198
+ options = that.options;
199
+
200
+ $(container).children().each(function(idx, el) {
201
+ if($(el).attr('ex:role') == 'lens') {
202
+ lenses.push(Exhibit.Lens(el, options));
203
+ }
204
+ });
205
+
206
+ that.getLens = function(item) {
207
+ for(i = 0, n = lenses.length; i < n; i++) {
208
+ if(lenses[i].isForItem(item)) {
209
+ return lenses[i];
210
+ }
211
+ }
212
+ return that.options.viewPanel.getLens(item);
213
+ }
214
+
215
+ that.eventModelChange = function(model) {
216
+ var template, cutpoints, tree, lens, i, n, item;
217
+
218
+ $(container).empty();
219
+ $(model.items()).each(function(idx, id) {
220
+ item = model.getItem(id);
221
+ lens = that.getLens(item);
222
+
223
+ $(lens.render(model, id)).appendTo($(container));
224
+ });
225
+
226
+ $("<div class='clear'></div>").appendTo($(container));
227
+ };
228
+
229
+ return that;
230
+ }
231
+
232
+ var parseSubcontentAttribute = function(value) {
233
+ var fragments = [ ],
234
+ current = 0,
235
+ open, close, n;
236
+
237
+ n = value.length;
238
+ while( current < n && (open = value.indexOf("{{", current)) >= 0) {
239
+ close = value.indexOf("}}", open);
240
+ if(close < 0) { break; }
241
+
242
+ fragments.push(value.substring(current, open));
243
+ fragments.push(Exhibit.ExpressionParser().parse(value.substring(open+2, close)));
244
+
245
+ current = close + 2;
246
+ }
247
+ if(current < n) {
248
+ fragments.push(value.substr(current));
249
+ }
250
+ return fragments;
251
+ };
252
+
253
+ var processors = { };
254
+
255
+ processors.TemplateNode = function(node) {
256
+ if(node.nodeType == 1) {
257
+ return processors.TemplateElement(node);
258
+ }
259
+ else {
260
+ return node.nodeValue;
261
+ }
262
+ };
263
+
264
+ processors.TemplateElement = function(elmt) {
265
+ var that = {
266
+ tag: elmt.tagName.toLowerCase(),
267
+ control: null,
268
+ condition: null,
269
+ content: null,
270
+ contentAttributes: null,
271
+ subcontentAttributes: null,
272
+ attributes: [],
273
+ styles: [],
274
+ handlers: [],
275
+ children: null
276
+ },
277
+ expressionParser = Exhibit.ExpressionParser(),
278
+ parseChildNodes = true,
279
+ attributes = elmt.attributes,
280
+ i, n, attribute, name, value, childNode;
281
+
282
+ for(i = 0, n = attributes.length; i < n; i++) {
283
+ attribute = attributes[i];
284
+ name = attribute.nodeName;
285
+ value = attribute.nodeValue;
286
+
287
+ if(value == null || typeof(value) != "string" || value.length ==0 || name == "contentEditable") {
288
+ continue;
289
+ }
290
+
291
+ if( name == "ex:onshow" ) {
292
+ templateNode.attributes.push({
293
+ name: name,
294
+ value: value
295
+ });
296
+ }
297
+ else if( name.length > 3 && name.substr(0,3) == "ex:" ) {
298
+ name = name.substr(3);
299
+ if( name == "formats" ) {
300
+ }
301
+ else if( name == "control" ) {
302
+ that.control = value;
303
+ }
304
+ else if( name == "content" ) {
305
+ that.content = expressionParser.parse(value);
306
+ parseChildNodes = false;
307
+ }
308
+ else if( name == "if-exists" ) {
309
+ that.condition = {
310
+ test: "if-exists",
311
+ expression: expressionParser.parse(value)
312
+ };
313
+ }
314
+ else if( name == "if") {
315
+ that.condition = {
316
+ test: "if",
317
+ expression: expressionParser.parse(value)
318
+ };
319
+ }
320
+ else if( name == "select") {
321
+ that.condition = {
322
+ test: "select",
323
+ expression: expressionParser.parse(value)
324
+ };
325
+ }
326
+ else if( name == "case") {
327
+ that.condition = {
328
+ test: "case",
329
+ expression: expressionParser.parse(value)
330
+ };
331
+ }
332
+ else if( name.substr(name.length - 8, 8) == "-content" ) {
333
+ if( that.contentAttributes == null ) {
334
+ that.contentAttributes = [ ];
335
+ }
336
+ that.contentAttributes.push({
337
+ name: name.substr(0, name.length-8),
338
+ expression: Exhibit.ExpressionParser().parse(value),
339
+ isStyle: false
340
+ });
341
+ }
342
+ else if( name.substr(name.length - 11, 11) == "-subcontent" ) {
343
+ if( that.subcontentAttributes == null ) {
344
+ that.subcontentAttributes = [ ];
345
+ }
346
+ that.subcontentAttributes.push({
347
+ name: name.substr(0, name.length-11),
348
+ expression: parseSubcontentAttribute(value),
349
+ isStyle: false
350
+ });
351
+ }
352
+ else {
353
+ }
354
+ }
355
+ else if( name == "style") {
356
+ }
357
+ }
358
+
359
+ // handle handlers
360
+
361
+ childNode = elmt.firstChild;
362
+ if( childNode != null && parseChildNodes ) {
363
+ that.children = [ ];
364
+ while( childNode != null ) {
365
+ if( childNode.nodeType == 3 || childNode.nodeType == 1 ) {
366
+ that.children.push(processors.TemplateNode(childNode));
367
+ }
368
+ childNode = childNode.nextSibling;
369
+ }
370
+ }
371
+
372
+ return that;
373
+ };
374
+
375
+ Exhibit.DefaultLens = function(options) {
376
+ var that = { },
377
+ template = { };
378
+
379
+ that.render = function(model, itemID) {
380
+ var text, item = model.getItem(itemID);
381
+
382
+ text = "<table><tr><td colspan='2'>" +
383
+ item.label + "</td></tr>";
384
+
385
+ $.each(item, function(idx, prop) {
386
+ text += "<tr><td>" + idx + ":</td><td>" + prop + "</td></tr>";
387
+ });
388
+
389
+ text += "</table>";
390
+ return text;
391
+ };
392
+
393
+ that.isForItem = function(item) { return true; };
394
+
395
+ return that;
396
+ };
397
+
398
+ Exhibit.Lens = function(container, options) {
399
+ var that = fluid.initView("Fabulator.Exhibit.Lens", container, options),
400
+ types,
401
+ template = new Array();
402
+ options = that.options;
403
+
404
+ types = $(container).attr("ex:itemTypes").split(/,\s*/);
405
+
406
+ template = processors.TemplateNode(container);
407
+
408
+ that.render = function(model, itemID) {
409
+ var div = document.createElement("div"),
410
+ old_div = template.elmt,
411
+ result;
412
+ template.elmt = div;
413
+ result = model.renderTemplate(itemID, template);
414
+ template.elmt = old_div;
415
+ return result.elmt;
416
+ };
417
+
418
+ that.isForItem = function(item) {
419
+ var i, j, n, m;
420
+
421
+ n = types.length;
422
+
423
+ if(n == 0) {
424
+ return true;
425
+ }
426
+
427
+ if(typeof(item.type) == "undefined") {
428
+ return false;
429
+ }
430
+
431
+ if(typeof(item.type) == "string") {
432
+ for(i = 0; i < n; i+=1) {
433
+ if(item.type == types[i]) {
434
+ return true;
435
+ }
436
+ }
437
+ }
438
+ else {
439
+ m = item.type.length;
440
+ for(i = 0; i < n; i += 1 ) {
441
+ for(j = 0; j < m; j += 1 ) {
442
+ if(item.type[j] == types[i]) {
443
+ return true;
444
+ }
445
+ }
446
+ }
447
+ }
448
+
449
+ return false;
450
+ };
451
+
452
+ return that;
453
+ };
454
+ })(jQuery, Fabulator.Exhibit);
455
+
456
+ fluid.defaults("Fabulator.Exhibit.Presentations", {
457
+ });