drogus-gadgeteer 0.3.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.
@@ -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);