drogus-gadgeteer 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,372 @@
1
+ /*! Copyright (c) 2009 László Bácsi (http://icanscale.com)
2
+ * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
3
+ *
4
+ * Version: 0.3
5
+ * Requires opensocial-jQuery 1.0.4+
6
+ */
7
+
8
+ (function($) {
9
+
10
+ $.gadgeteer = function(callback, options) {
11
+ // If called with callback, notify it if we're ready
12
+ if ($.isFunction(callback)) {
13
+ if ($.gadgeteer.options) {
14
+ return false;
15
+ } else {
16
+ $.gadgeteer.options = options = options || {};
17
+ }
18
+ $.gadgeteer.defaultTarget = options.defaultTarget || '#page';
19
+ $.gadgeteer.host = options.host || '';
20
+
21
+ // Setup link behaviours
22
+ $.gadgeteer.linkBehaviours = options.linkBehaviours || {};
23
+ if (!options.noAjaxLinks) {
24
+ $('a').livequery('click', function(e) {
25
+ $.gadgeteer.handleLinkBehaviour.call($(this), e);
26
+ }).removeAttr('onclick');
27
+ }
28
+
29
+ if (!options.noAjaxForms) {
30
+ // Making sure submit input element values are submitted
31
+ $('form input[type=submit]').livequery('click', function(e) {
32
+ $(this).parents('form:eq(0)').data('submitClicked', $(this));
33
+ });
34
+ // All forms will submit through an ajax call
35
+ $('form').livequery('submit', function(e) {
36
+ e.preventDefault();
37
+ var form = $(this);
38
+ var action = form.attr('action');
39
+ var target = form.hasClass('silent') ? null : $.gadgeteer.defaultTarget;
40
+ var params = [$.param(form.formToArray()), $.param($.gadgeteer.viewer.osParams()), $.param($.gadgeteer.owner.osParams())];
41
+ var submit = form.data('submitClicked');
42
+ if (submit) {
43
+ if (submit.attr('name')) {
44
+ var param = {};
45
+ param[submit.attr('name')] = submit.val();
46
+ params.push($.param(param));
47
+ }
48
+ if ($.gadgeteer.options.submitSendingMessage) {
49
+ submit.data('oldValue', submit.val());
50
+ submit.val($.gadgeteer.options.submitSendingMessage).get(0).disabled = true;
51
+ }
52
+ form.data('submitClicked', null);
53
+ }
54
+ action = $.gadgeteer.expandUri(action);
55
+ $.ajax({
56
+ url: action,
57
+ type: form.attr('method') || 'GET',
58
+ data: params.join("&"),
59
+ dataType: 'html',
60
+ oauth: 'signed',
61
+ target: target,
62
+ complete: function(request, status) {
63
+ if (submit) {
64
+ var oldValue = submit.data('oldValue');
65
+ if (oldValue) {
66
+ submit.val(oldValue).get(0).disabled = false;
67
+ submit.data('oldValue', null);
68
+ }
69
+ }
70
+ }
71
+ });
72
+ });
73
+ }
74
+
75
+ // Setup ajax event callbacks
76
+ $(document).ajaxSend(function(e, request, settings) {
77
+ if (settings.target && $.gadgeteer.options.loadingMessage) {
78
+ $(settings.target).append($.gadgeteer.loadingElem());
79
+ }
80
+ }).ajaxSuccess(function(e, request, settings) {
81
+ $.gadgeteer.currentUrl = request.url;
82
+ if (settings.target) {
83
+ var html = request.responseText;
84
+ $(settings.target).html(html);
85
+ }
86
+ // !iframe
87
+ $(window).adjustHeight();
88
+ // Do another adjustHeight in 250ms just to be sure
89
+ setTimeout(function() {$(window).adjustHeight();}, 250);
90
+ }).ajaxError(function(e, request, settings, exception) {
91
+ if (settings.target && request.status.toString().charAt(0) != '3') {
92
+ var html = request.responseText;
93
+ $(settings.target).html(html);
94
+ // !iframe
95
+ $(window).adjustHeight();
96
+ // Do another adjustHeight in 250ms just to be sure
97
+ setTimeout(function() {$(window).adjustHeight();}, 250);
98
+ }
99
+ }).ajaxComplete(function(e, request, settings) {
100
+ if (request.status.toString().charAt(0) == '3') {
101
+ var href = request.getResponseHeader('Location') || request.getResponseHeader('location');
102
+ // hackish way to determine if we have an array (depends on the fact that the real href must be longer than 1 char)
103
+ if (!href.charAt) href = href[0];
104
+ href = $.gadgeteer.expandUri(href);
105
+ var params = '';
106
+ if (settings.auth == 'signed' || !$.gadgeteer.options.dontAddOsParams) {
107
+ params = $.param($.gadgeteer.viewer.osParams()) + '&' + $.param($.gadgeteer.owner.osParams())
108
+ }
109
+ $.ajax({
110
+ url: href,
111
+ type: 'GET',
112
+ data: params,
113
+ dataType: 'html',
114
+ oauth: settings.auth,
115
+ target: settings.target
116
+ });
117
+ }
118
+ });
119
+
120
+ // Wait for everything to load then call the callback
121
+ setTimeout(function() {
122
+ if ($.gadgeteer.viewer && $.gadgeteer.owner && $.gadgeteer.data && $.gadgeteer.owner.data) {
123
+ // Navigate away if params tell so
124
+ var params = gadgets.views.getParams();
125
+ var navTo = params.navigateTo;
126
+ if (navTo) {
127
+ // Tell the callback that we're navigating away
128
+ callback(true);
129
+ $.gadgeteer.simpleRequest(navTo, {signed: params.signedNavigate});
130
+ } else {
131
+ callback();
132
+ }
133
+ } else {
134
+ setTimeout(arguments.callee, 50);
135
+ }
136
+ }, 50);
137
+ }
138
+ }
139
+
140
+ $.extend($.gadgeteer, {
141
+ loadingElem: function() {
142
+ if ($.gadgeteer.LOADING_ELEM) return $.gadgeteer.LOADING_ELEM;
143
+
144
+ var loading = $('#loading');
145
+ if (loading.length < 1) {
146
+ loading = $('<div id="loading">'+$.gadgeteer.options.loadingMessage+'</div>');
147
+ }
148
+ return $.gadgeteer.LOADING_ELEM = loading;
149
+ },
150
+
151
+ expandUri: function(uri, options) {
152
+ if (uri.charAt(0) == '/') uri = $.gadgeteer.host + uri;
153
+ if (!options) options = {};
154
+ if (!$.gadgeteer.options.dontExpand) {
155
+ if ($.gadgeteer.viewer) {
156
+ uri = uri.replace(/(?:(\/)|{)viewer(?:}|([\/\?#]|$))/g, '$1'+$.gadgeteer.viewer.backendId+'$2');
157
+ }
158
+ if ($.gadgeteer.owner) {
159
+ uri = uri.replace(/(?:(\/)|{)owner(?:}|([\/\?#]|$))/g, '$1'+$.gadgeteer.owner.backendId+'$2');
160
+ }
161
+ }
162
+ if (options.addParams) {
163
+ var params = $.param($.extend(false, $.gadgeteer.viewer.osParams(), $.gadgeteer.owner.osParams()));
164
+ uri += (uri.indexOf('?') != -1 ? '&' : '?') + params;
165
+ } else if (options.addProfileIds) {
166
+ var params = {};
167
+ if (uri.indexOf('os_viewer_id') == -1) params.os_viewer_id = $.gadgeteer.viewer.id;
168
+ if (uri.indexOf('os_owner_id') == -1) params.os_owner_id = $.gadgeteer.owner.id;
169
+ uri += (uri.indexOf('?') != -1 ? '&' : '?') + $.param(params);
170
+ }
171
+ return uri;
172
+ },
173
+
174
+ simpleRequest: function(href, options) {
175
+ var params = (options.data === undefined ? {} : options.data);
176
+ if (options === undefined) options = {};
177
+ if (options.addProfileIds) {
178
+ if (href.indexOf('os_viewer_id') == -1) params.os_viewer_id = $.gadgeteer.viewer.id;
179
+ if (href.indexOf('os_owner_id') == -1) params.os_owner_id = $.gadgeteer.owner.id;
180
+ }
181
+ if (options.signed) {
182
+ params = $.extend(false, params, $.gadgeteer.viewer.osParams(), $.gadgeteer.owner.osParams());
183
+ }
184
+ href = $.gadgeteer.expandUri(href);
185
+ options = $.extend(
186
+ { // defaults
187
+ type: 'GET',
188
+ dataType: 'html'
189
+ }, options, { // force options
190
+ data: $.param(params),
191
+ url: href,
192
+ oauth: options.signed && 'signed',
193
+ target: options.target === undefined ? $($.gadgeteer.defaultTarget) : options.target
194
+ }
195
+ );
196
+ $.ajax(options);
197
+ },
198
+
199
+ regularRequest: function(e) {
200
+ // regular request (i.e. normal anchor click through) is a no-op
201
+ },
202
+
203
+ ajaxRequest: function(e) {
204
+ e.preventDefault();
205
+ var host = document.location.host;
206
+ var link = $(this);
207
+ var href = link.attr('href');
208
+ var _href = link[0].getAttribute('href');
209
+
210
+ //hack for IE href attr bug
211
+ if (_href.match(host)) {
212
+ var l = _href.search(host)+host.length;
213
+ href = _href.substring(l);
214
+ }
215
+
216
+ var params = {};
217
+ var method = link.hasClass('post') ? 'post' : link.hasClass('put') ? 'put' : link.hasClass('delete') ? 'delete' : 'get';
218
+ if (method != 'get') params._method = method;
219
+ if (link.hasClass('signed')) {
220
+ params = $.extend(false, params, $.gadgeteer.viewer.osParams(), $.gadgeteer.owner.osParams());
221
+ } else if (!$.gadgeteer.options.dontAddOsParams) {
222
+ params = $.extend(false, params, {os_viewer_id: $.gadgeteer.viewer.id, os_owner_id: $.gadgeteer.owner.id});
223
+ }
224
+
225
+ var target = link.hasClass('silent') ? null : $.gadgeteer.defaultTarget;
226
+ href = $.gadgeteer.expandUri(href);
227
+ $.ajax({
228
+ type: method == 'get' ? 'GET' : 'POST',
229
+ url: href,
230
+ data: params,
231
+ dataType: target ? 'html' : null,
232
+ oauth: link.hasClass('signed') ? 'signed' : null,
233
+ target: target
234
+ });
235
+ },
236
+
237
+ navigateRequest: function(view, params, ownerId, e) {
238
+ if (e !== undefined) {
239
+ e.preventDefault();
240
+ }
241
+ view = gadgets.views.getSupportedViews()[view];
242
+ gadgets.views.requestNavigateTo(view, params, ownerId);
243
+ },
244
+
245
+ handleLinkBehaviour: function(e) {
246
+ var link = $(this);
247
+ var matched = false;
248
+ $.each($.gadgeteer.linkBehaviours, function(behaviour, callback) {
249
+ var match;
250
+ if ($.isFunction(callback) && (match = callback.call(link, e))) {
251
+ var params = match === true ? [] : ($.isFunction(match.push) ? match : Array(match));
252
+ params.push(e);
253
+ //console.log('calling ', behaviour, ' link behaviour for ', link, ' with ', params);
254
+ var handler = behaviour+'Request';
255
+ handler = $.gadgeteer.linkBehaviours.handlers && $.gadgeteer.linkBehaviours.handlers[handler] || $.gadgeteer[handler];
256
+ handler.apply(link, params);
257
+ matched = true;
258
+ return false;
259
+ }
260
+ });
261
+ if (!matched) {
262
+ var def = $.gadgeteer.linkBehaviours.defaultBehavior || 'ajax';
263
+ //console.log('calling DEFAULT ', def, ' link behaviour for ', link, ' with ', e);
264
+ $.gadgeteer[def+'Request'].call(link, e);
265
+ }
266
+ },
267
+
268
+ appLink: function(parameters) {
269
+ return gadgets.views.bind(gadgets.config.get('views')['canvas'].urlTemplate, {
270
+ appId: document.location.host.match(/(\d+)\./)[1],
271
+ viewParams: encodeURIComponent(gadgets.json.stringify(parameters))
272
+ });
273
+ }
274
+ });
275
+
276
+ // Initialize gadgeteer
277
+ $(function() {
278
+ // Get information about the viewer and owner
279
+ var osd = opensocial.data.DataContext;
280
+ function finalizeData(person, data, fromosd) {
281
+ for (var id in data) {
282
+ data = data[id];
283
+ break;
284
+ }
285
+ if (fromosd) {
286
+ for (var key in data) {
287
+ data[key] = gadgets.json.parse(data[key]);
288
+ }
289
+ }
290
+ $.gadgeteer[person].data = function(key, value, cb) {
291
+ if (value === undefined) {
292
+ return data[key];
293
+ } else {
294
+ var oldValue = data[key];
295
+ data[key] = value;
296
+ var params = {};
297
+ params[key] = value;
298
+ var tries = 3;
299
+ (function() {
300
+ var callee = arguments.callee;
301
+ $.ajax({
302
+ type: 'POST', url: '/appdata/@'+person, data: params,
303
+ dataType: 'data', success: cb,
304
+ error: function(event, request, settings, thrownError) {
305
+ console.warn('error requesting appdata update (try #'+(3-tries+1)+')', event, request, settings, thrownError);
306
+ if (tries--) {
307
+ callee();
308
+ } else { // resetting old value
309
+ data[key] = oldValue;
310
+ cb(null, 'failure');
311
+ }
312
+ }
313
+ });
314
+ })();
315
+ return value;
316
+ }
317
+ };
318
+ if (person == 'viewer') {
319
+ $.gadgeteer.data = $.gadgeteer[person].data;
320
+ }
321
+ }
322
+ function finalizePerson(person) {
323
+ $.gadgeteer[person].osParams = function() {
324
+ var params = {};
325
+ for (var attr in $.gadgeteer[person]) {
326
+ if (!$.isFunction($.gadgeteer[person][attr])) {
327
+ var underscore = attr.replace(/([A-Z])/, '_$1').toLowerCase();
328
+ if (typeof $.gadgeteer[person][attr] == "object") {
329
+ for (subattr in $.gadgeteer[person][attr]) {
330
+ var subus = subattr.replace(/([A-Z])/, '_$1').toLowerCase();
331
+ params['os_'+person+'_'+underscore+'['+subus+']'] = $.gadgeteer[person][attr][subattr];
332
+ }
333
+ } else {
334
+ params['os_'+person+'_'+underscore] = $.gadgeteer[person][attr];
335
+ }
336
+ }
337
+ }
338
+ return params;
339
+ };
340
+ if (!$.gadgeteer.options.dontSwapDots) {
341
+ $.gadgeteer[person].backendId = $.gadgeteer[person].id.replace(/\./g, '-');
342
+ } else {
343
+ $.gadgeteer[person].backendId = $.gadgeteer[person].id;
344
+ }
345
+ var data;
346
+ if (osd && (data = osd.getDataSet(person+'Data'))) {
347
+ finalizeData(person, data, true);
348
+ } else {
349
+ $.getData('/appdata/@'+person, function(data, status) {
350
+ finalizeData(person, data);
351
+ });
352
+ }
353
+ }
354
+ function setupPerson(person) {
355
+ if (osd && ($.gadgeteer[person] = osd.getDataSet(person))) {
356
+ finalizePerson(person);
357
+ } else {
358
+ $.getData('/people/@'+person+'/@self', function(data, status) {
359
+ $.gadgeteer[person] = data[0];
360
+ finalizePerson(person);
361
+ });
362
+ }
363
+ }
364
+ setupPerson('viewer');
365
+ setupPerson('owner');
366
+ });
367
+
368
+ if (typeof $g == "undefined") {
369
+ $g = $.gadgeteer;
370
+ }
371
+
372
+ })(jQuery);
@@ -0,0 +1,226 @@
1
+ /*! Copyright (c) 2009 Brandon Aaron (http://brandonaaron.net)
2
+ * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
3
+ * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
4
+ *
5
+ * Version: 1.1.0-pre
6
+ * Requires jQuery 1.3+
7
+ * Docs: http://docs.jquery.com/Plugins/livequery
8
+ */
9
+
10
+ (function($) {
11
+
12
+ $.extend($.fn, {
13
+ livequery: function(type, fn, fn2) {
14
+ var self = this, q;
15
+
16
+ // Handle different call patterns
17
+ if ($.isFunction(type))
18
+ fn2 = fn, fn = type, type = undefined;
19
+
20
+ // See if Live Query already exists
21
+ $.each( $.livequery.queries, function(i, query) {
22
+ if ( self.selector == query.selector && self.context == query.context &&
23
+ type == query.type && (!fn || fn.$lqguid == query.fn.$lqguid) && (!fn2 || fn2.$lqguid == query.fn2.$lqguid) )
24
+ // Found the query, exit the each loop
25
+ return (q = query) && false;
26
+ });
27
+
28
+ // Create new Live Query if it wasn't found
29
+ q = q || new $.livequery(this.selector, this.context, type, fn, fn2);
30
+
31
+ // Make sure it is running
32
+ q.stopped = false;
33
+
34
+ // Run it immediately for the first time
35
+ q.run();
36
+
37
+ // Contnue the chain
38
+ return this;
39
+ },
40
+
41
+ expire: function(type, fn, fn2) {
42
+ var self = this;
43
+
44
+ // Handle different call patterns
45
+ if ($.isFunction(type))
46
+ fn2 = fn, fn = type, type = undefined;
47
+
48
+ // Find the Live Query based on arguments and stop it
49
+ $.each( $.livequery.queries, function(i, query) {
50
+ if ( self.selector == query.selector && self.context == query.context &&
51
+ (!type || type == query.type) && (!fn || fn.$lqguid == query.fn.$lqguid) && (!fn2 || fn2.$lqguid == query.fn2.$lqguid) && !this.stopped )
52
+ $.livequery.stop(query.id);
53
+ });
54
+
55
+ // Continue the chain
56
+ return this;
57
+ }
58
+ });
59
+
60
+ $.livequery = function(selector, context, type, fn, fn2) {
61
+ this.selector = selector;
62
+ this.context = context;
63
+ this.type = type;
64
+ this.fn = fn;
65
+ this.fn2 = fn2;
66
+ this.elements = [];
67
+ this.stopped = false;
68
+
69
+ // The id is the index of the Live Query in $.livequery.queries
70
+ this.id = $.livequery.queries.push(this)-1;
71
+
72
+ // Mark the functions for matching later on
73
+ fn.$lqguid = fn.$lqguid || $.livequery.guid++;
74
+ if (fn2) fn2.$lqguid = fn2.$lqguid || $.livequery.guid++;
75
+
76
+ // Return the Live Query
77
+ return this;
78
+ };
79
+
80
+ $.livequery.prototype = {
81
+ stop: function() {
82
+ var query = this;
83
+
84
+ if ( this.type )
85
+ // Unbind all bound events
86
+ this.elements.unbind(this.type, this.fn);
87
+ else if (this.fn2)
88
+ // Call the second function for all matched elements
89
+ this.elements.each(function(i, el) {
90
+ query.fn2.apply(el);
91
+ });
92
+
93
+ // Clear out matched elements
94
+ this.elements = [];
95
+
96
+ // Stop the Live Query from running until restarted
97
+ this.stopped = true;
98
+ },
99
+
100
+ run: function() {
101
+ // Short-circuit if stopped
102
+ if ( this.stopped ) return;
103
+ var query = this;
104
+
105
+ var oEls = this.elements,
106
+ els = $(this.selector, this.context),
107
+ nEls = els.not(oEls);
108
+
109
+ // Set elements to the latest set of matched elements
110
+ this.elements = els;
111
+
112
+ if (this.type) {
113
+ // Bind events to newly matched elements
114
+ nEls.bind(this.type, this.fn);
115
+
116
+ // Unbind events to elements no longer matched
117
+ if (oEls.length > 0)
118
+ $.each(oEls, function(i, el) {
119
+ if ( $.inArray(el, els) < 0 )
120
+ $.event.remove(el, query.type, query.fn);
121
+ });
122
+ }
123
+ else {
124
+ // Call the first function for newly matched elements
125
+ nEls.each(function() {
126
+ query.fn.apply(this);
127
+ });
128
+
129
+ // Call the second function for elements no longer matched
130
+ if ( this.fn2 && oEls.length > 0 )
131
+ $.each(oEls, function(i, el) {
132
+ if ( $.inArray(el, els) < 0 )
133
+ query.fn2.apply(el);
134
+ });
135
+ }
136
+ }
137
+ };
138
+
139
+ $.extend($.livequery, {
140
+ guid: 0,
141
+ queries: [],
142
+ queue: [],
143
+ running: false,
144
+ timeout: null,
145
+
146
+ checkQueue: function() {
147
+ if ( $.livequery.running && $.livequery.queue.length ) {
148
+ var length = $.livequery.queue.length;
149
+ // Run each Live Query currently in the queue
150
+ while ( length-- )
151
+ $.livequery.queries[ $.livequery.queue.shift() ].run();
152
+ }
153
+ },
154
+
155
+ pause: function() {
156
+ // Don't run anymore Live Queries until restarted
157
+ $.livequery.running = false;
158
+ },
159
+
160
+ play: function() {
161
+ // Restart Live Queries
162
+ $.livequery.running = true;
163
+ // Request a run of the Live Queries
164
+ $.livequery.run();
165
+ },
166
+
167
+ registerPlugin: function() {
168
+ $.each( arguments, function(i,n) {
169
+ // Short-circuit if the method doesn't exist
170
+ if (!$.fn[n]) return;
171
+
172
+ // Save a reference to the original method
173
+ var old = $.fn[n];
174
+
175
+ // Create a new method
176
+ $.fn[n] = function() {
177
+ // Call the original method
178
+ var r = old.apply(this, arguments);
179
+
180
+ // Request a run of the Live Queries
181
+ $.livequery.run();
182
+
183
+ // Return the original methods result
184
+ return r;
185
+ }
186
+ });
187
+ },
188
+
189
+ run: function(id) {
190
+ if (id != undefined) {
191
+ // Put the particular Live Query in the queue if it doesn't already exist
192
+ if ( $.inArray(id, $.livequery.queue) < 0 )
193
+ $.livequery.queue.push( id );
194
+ }
195
+ else
196
+ // Put each Live Query in the queue if it doesn't already exist
197
+ $.each( $.livequery.queries, function(id) {
198
+ if ( $.inArray(id, $.livequery.queue) < 0 )
199
+ $.livequery.queue.push( id );
200
+ });
201
+
202
+ // Clear timeout if it already exists
203
+ if ($.livequery.timeout) clearTimeout($.livequery.timeout);
204
+ // Create a timeout to check the queue and actually run the Live Queries
205
+ $.livequery.timeout = setTimeout($.livequery.checkQueue, 20);
206
+ },
207
+
208
+ stop: function(id) {
209
+ if (id != undefined)
210
+ // Stop are particular Live Query
211
+ $.livequery.queries[ id ].stop();
212
+ else
213
+ // Stop all Live Queries
214
+ $.each( $.livequery.queries, function(id) {
215
+ $.livequery.queries[ id ].stop();
216
+ });
217
+ }
218
+ });
219
+
220
+ // Register core DOM manipulation methods
221
+ $.livequery.registerPlugin('append', 'prepend', 'after', 'before', 'wrap', 'attr', 'removeAttr', 'addClass', 'removeClass', 'toggleClass', 'empty', 'remove');
222
+
223
+ // Run Live Queries when the Document is ready
224
+ $(function() { $.livequery.play(); });
225
+
226
+ })(jQuery);