virgo-gadgeteer 0.2.2
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.
- data/LICENSE +1 -0
- data/README.rdoc +49 -0
- data/Rakefile +42 -0
- data/VERSION.yml +4 -0
- data/bin/gadgeteer +224 -0
- data/javascripts/jquery.gadgeteer.js +230 -0
- data/javascripts/jquery.livequery.js +250 -0
- data/javascripts/opensocial-jquery.js +4325 -0
- data/lib/gadgeteer.rb +106 -0
- data/lib/sinatra/gadgeteer.rb +3 -0
- data/rails/init.rb +3 -0
- data/templates/canvas.haml +16 -0
- data/templates/gadget.haml +11 -0
- data/templates/gadget.js +9 -0
- data/templates/gadget.rb +7 -0
- data/templates/gadget.yml +23 -0
- data/templates/gadgets_controller.rb +6 -0
- data/test/gadgeteer_test.rb +7 -0
- data/test/test_helper.rb +10 -0
- metadata +72 -0
data/LICENSE
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Copyright (c) 2009 Virgo Systems Kft., released under the MIT license
|
data/README.rdoc
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
Gadgeteer simplifies OpenSocial Gadget development by giving you helpers you can use in your Rails application to verify Signed Requests and access OpenSocial data.
|
2
|
+
|
3
|
+
= Requirements
|
4
|
+
|
5
|
+
Gadgeteer requires the {oauth gem}[http://github.com/pelle/oauth/tree/master] (0.2.7+).
|
6
|
+
|
7
|
+
*Note*: the current version of the oauth gem doesn't comply completely with the OAuth standard, and also doesn't work with Rails 2.3</tt>. You can use {lackac's fork}[http://github.com/lackac/oauth/tree/master], until the fixes are merged in.
|
8
|
+
|
9
|
+
= Usage
|
10
|
+
|
11
|
+
You can configure the secrets and public keys used by your application two ways.
|
12
|
+
|
13
|
+
For consumer secrets you can put your consumer key/secret pairs into <tt>config/oauth_secrets.yml</tt>:
|
14
|
+
|
15
|
+
key: secret
|
16
|
+
|
17
|
+
or you could setup those in your ApplicationController:
|
18
|
+
|
19
|
+
class ApplicationController < ActionController::Base
|
20
|
+
|
21
|
+
oauth_secrets['key'] = 'secret'
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
For public keys you can put the certificates into <tt>config/certs</tt> with <tt>.cert</tt> extension, or you could setup the public keys in your ApplicationController by creating a <tt>OpenSSL::PKey::RSA</tt> object and adding it to the <tt>public_keys</tt> hash:
|
26
|
+
|
27
|
+
class ApplicationController < ActionController::Base
|
28
|
+
|
29
|
+
public_keys['example.com'] = OpenSSL::PKey::RSA.new(OpenSSL::X509::Certificate.new(CERT).public_key)
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
You can use the <tt>verify_signature</tt> method as a before_filter in your controllers to make sure the signed requests are correct:
|
34
|
+
|
35
|
+
class SecretNotesController < ActionController::Base
|
36
|
+
|
37
|
+
before_filter :verify_signature
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
The correct secret or public key will be used for verification based on the current request. If the <tt>xoauth_signature_publickey</tt> parameter is set, the corresponding public key will be used. Otherwise the consumer secret connected to the key found in the <tt>oauth_consumer_key</tt> parameter will be used. The singature will be verified based on this key/secret pair and the singature method set in the parameters.
|
42
|
+
|
43
|
+
If there are OpenSocial related request parameters, you can access them with the <tt>open_social</tt> method:
|
44
|
+
|
45
|
+
def index
|
46
|
+
@secret_notes = SecretNote.find_by_profile_id(open_social[:viewer_id])
|
47
|
+
end
|
48
|
+
|
49
|
+
Copyright (c) 2009 Virgo Systems Kft., released under the MIT license
|
data/Rakefile
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
require 'rcov/rcovtask'
|
5
|
+
|
6
|
+
begin
|
7
|
+
require 'jeweler'
|
8
|
+
Jeweler::Tasks.new do |s|
|
9
|
+
s.name = "gadgeteer"
|
10
|
+
s.summary = %Q{Making it easy to develop OpenSocial gadgets with Rails or Sinatra.}
|
11
|
+
s.email = "bacsi.laszlo@virgo.hu"
|
12
|
+
s.homepage = "http://github.com/virgo/gadgeteer"
|
13
|
+
s.description = "Making it easy to develop OpenSocial gadgets with Rails or Sinatra."
|
14
|
+
s.authors = ["Laszlo Bacsi"]
|
15
|
+
s.executables = ["gadgeteer"]
|
16
|
+
s.files = FileList['lib/**/*.rb', 'bin/*', '[A-Z]*', 'test/**/*', 'templates/*', 'javascripts/*.js', 'rails/*'].to_a
|
17
|
+
end
|
18
|
+
rescue LoadError
|
19
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
20
|
+
end
|
21
|
+
|
22
|
+
Rake::TestTask.new do |t|
|
23
|
+
t.libs << 'lib'
|
24
|
+
t.pattern = 'test/**/*_test.rb'
|
25
|
+
t.verbose = false
|
26
|
+
end
|
27
|
+
|
28
|
+
Rake::RDocTask.new do |rdoc|
|
29
|
+
rdoc.rdoc_dir = 'rdoc'
|
30
|
+
rdoc.title = 'gadgeteer'
|
31
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
32
|
+
rdoc.rdoc_files.include('README*')
|
33
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
34
|
+
end
|
35
|
+
|
36
|
+
Rcov::RcovTask.new do |t|
|
37
|
+
t.libs << 'test'
|
38
|
+
t.test_files = FileList['test/**/*_test.rb']
|
39
|
+
t.verbose = true
|
40
|
+
end
|
41
|
+
|
42
|
+
task :default => :rcov
|
data/VERSION.yml
ADDED
data/bin/gadgeteer
ADDED
@@ -0,0 +1,224 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$usage = <<USAGE
|
4
|
+
== Synopsis
|
5
|
+
This script generates some files for you to start coding your gadget with.
|
6
|
+
|
7
|
+
== Examples
|
8
|
+
For a Rails project:
|
9
|
+
gadgeteer --rails Gadget
|
10
|
+
|
11
|
+
For a Sinatra project:
|
12
|
+
gadgeteer --sinatra Gadget
|
13
|
+
|
14
|
+
== Usage
|
15
|
+
gadgeteer <--rails|--sinatra> [options] ModelName
|
16
|
+
|
17
|
+
For help use: gadgeteer -h
|
18
|
+
|
19
|
+
== Options
|
20
|
+
-h, --help Displays help message
|
21
|
+
-V, --version Display the version, then exit
|
22
|
+
-q, --quiet Output as little as possible, overrides verbose
|
23
|
+
-v, --verbose Verbose output
|
24
|
+
-r, --rails Generates files for a Rails app
|
25
|
+
-s, --sinatra Generates files for a Sinatra app
|
26
|
+
-f, --force Overwrite existing files
|
27
|
+
-a, --author me Name of the author (for gadget.xml)
|
28
|
+
-e, --email i@me.us Email address of the author (for gadget.xml)
|
29
|
+
|
30
|
+
== Author
|
31
|
+
László Bácsi
|
32
|
+
|
33
|
+
== Copyright
|
34
|
+
Copyright (c) 2009 Virgo Systems Kft. Licensed under the MIT License:
|
35
|
+
http://www.opensource.org/licenses/mit-license.php
|
36
|
+
USAGE
|
37
|
+
|
38
|
+
require 'optparse'
|
39
|
+
require 'rdoc/usage'
|
40
|
+
require 'ostruct'
|
41
|
+
require 'date'
|
42
|
+
|
43
|
+
require 'erb'
|
44
|
+
require 'yaml'
|
45
|
+
require 'activesupport'
|
46
|
+
|
47
|
+
module Gadgeteer
|
48
|
+
class App
|
49
|
+
VERSION_HASH = YAML.load_file(File.join(File.dirname(__FILE__), '..', 'VERSION.yml'))
|
50
|
+
VERSION = "#{VERSION_HASH[:major]}.#{VERSION_HASH[:minor]}.#{VERSION_HASH[:patch]}"
|
51
|
+
|
52
|
+
MAPPING = {
|
53
|
+
:rails => {
|
54
|
+
:files => {
|
55
|
+
"gadget.yml" => "config/:singular.yml",
|
56
|
+
"gadget.rb" => "app/models/:singular.rb",
|
57
|
+
"gadget.haml" => "app/views/:plural/show.xml.haml",
|
58
|
+
"canvas.haml" => "app/views/:plural/_canvas.html.haml",
|
59
|
+
"gadget.js" => "public/javascripts/:singular.js",
|
60
|
+
"gadgets_controller.rb" => "app/controllers/:plural_controller.rb"
|
61
|
+
},
|
62
|
+
:help => <<-HELP
|
63
|
+
Add this to your Rails application routes:
|
64
|
+
|
65
|
+
map.resource ::singular
|
66
|
+
HELP
|
67
|
+
},
|
68
|
+
:sinatra => {
|
69
|
+
:files => {
|
70
|
+
"gadget.yml" => "config/:singular.yml",
|
71
|
+
"gadget.rb" => ":singular.rb",
|
72
|
+
"gadget.haml" => "views/:singular.haml",
|
73
|
+
"canvas.haml" => "views/canvas.haml",
|
74
|
+
"gadget.js" => "public/javascripts/:singular.js"
|
75
|
+
},
|
76
|
+
:help => <<-HELP
|
77
|
+
Add this to your Sinatra application:
|
78
|
+
|
79
|
+
require 'sinatra/gadgeteer'
|
80
|
+
require ':singular'
|
81
|
+
|
82
|
+
get '/:singular.xml' do
|
83
|
+
haml ::singular
|
84
|
+
end
|
85
|
+
HELP
|
86
|
+
}
|
87
|
+
}
|
88
|
+
|
89
|
+
attr_reader :options
|
90
|
+
|
91
|
+
def initialize(arguments, stdin)
|
92
|
+
@arguments = arguments
|
93
|
+
@stdin = stdin
|
94
|
+
|
95
|
+
# Set defaults
|
96
|
+
@options = OpenStruct.new
|
97
|
+
@options.verbose = true
|
98
|
+
@options.quiet = false
|
99
|
+
@options.author = "Calvin"
|
100
|
+
@options.email = "calvin@example.com"
|
101
|
+
end
|
102
|
+
|
103
|
+
# Parse options, check arguments, then process the command
|
104
|
+
def run
|
105
|
+
if parsed_options? && arguments_valid?
|
106
|
+
process_arguments
|
107
|
+
process_command
|
108
|
+
else
|
109
|
+
output_usage
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
protected
|
114
|
+
|
115
|
+
def parsed_options?
|
116
|
+
# Specify options
|
117
|
+
opts = OptionParser.new
|
118
|
+
opts.on('-V', '--version') { output_version ; exit 0 }
|
119
|
+
opts.on('-h', '--help') { output_help }
|
120
|
+
opts.on('-v', '--verbose') { @options.verbose = true }
|
121
|
+
opts.on('-q', '--quiet') { @options.quiet = true }
|
122
|
+
opts.on('-r', '--rails') { @options.rails = true }
|
123
|
+
opts.on('-s', '--sinatra') { @options.sinatra = true }
|
124
|
+
opts.on('-f', '--force') { @options.force = true }
|
125
|
+
opts.on('-a', '--author AUTHOR') { |x| @options.author = x }
|
126
|
+
opts.on('-e', '--email EMAIL') { |x| @options.email = x }
|
127
|
+
|
128
|
+
opts.parse!(@arguments) rescue return false
|
129
|
+
|
130
|
+
process_options
|
131
|
+
end
|
132
|
+
|
133
|
+
# Performs post-parse processing on options
|
134
|
+
def process_options
|
135
|
+
@options.verbose = false if @options.quiet
|
136
|
+
@options.rails ^ @options.sinatra
|
137
|
+
end
|
138
|
+
|
139
|
+
# True if required arguments were provided
|
140
|
+
def arguments_valid?
|
141
|
+
true if @arguments.length == 1
|
142
|
+
end
|
143
|
+
|
144
|
+
# Setup the arguments
|
145
|
+
def process_arguments
|
146
|
+
@options.model = @arguments.first.classify
|
147
|
+
@options.title = @options.model.underscore.humanize
|
148
|
+
@options.singular = @options.model.underscore
|
149
|
+
@options.plural = @options.model.tableize
|
150
|
+
end
|
151
|
+
|
152
|
+
def output_help
|
153
|
+
output_version
|
154
|
+
usage_and_exit! #exits app
|
155
|
+
end
|
156
|
+
|
157
|
+
def output_usage
|
158
|
+
usage_and_exit! # gets usage from comments above
|
159
|
+
end
|
160
|
+
|
161
|
+
# Shamefully stolen from RDoc#usage. We cannot use RDoc::usage because
|
162
|
+
# RubyGems will call this from a wrapper, and #usage is hardcoded to look
|
163
|
+
# at the top-level file instead of the current one. I have changed this
|
164
|
+
# code to instead just parse a string.
|
165
|
+
def usage_and_exit!
|
166
|
+
markup = SM::SimpleMarkup.new
|
167
|
+
flow_convertor = SM::ToFlow.new
|
168
|
+
|
169
|
+
flow = markup.convert($usage, flow_convertor)
|
170
|
+
|
171
|
+
options = RI::Options.instance
|
172
|
+
formatter = options.formatter.new(options, "")
|
173
|
+
formatter.display_flow(flow)
|
174
|
+
|
175
|
+
exit(0)
|
176
|
+
end
|
177
|
+
|
178
|
+
def output_version
|
179
|
+
puts "#{$0} version #{VERSION}"
|
180
|
+
end
|
181
|
+
|
182
|
+
def process_command
|
183
|
+
key = @options.rails ? :rails : :sinatra
|
184
|
+
file_mapping = MAPPING[key][:files]
|
185
|
+
help = MAPPING[key][:help]
|
186
|
+
|
187
|
+
# Templates
|
188
|
+
file_mapping.each do |filename, target|
|
189
|
+
template = File.join(File.dirname(__FILE__), '..', 'templates', filename)
|
190
|
+
target = target.gsub(':singular', @options.singular).gsub(':plural', @options.plural)
|
191
|
+
if File.exists?(target) and not @options.force
|
192
|
+
puts "Skipping existing file #{target}" if @options.verbose
|
193
|
+
else
|
194
|
+
puts "Writing file #{target}" if @options.verbose
|
195
|
+
FileUtils.mkdir_p(File.dirname(target))
|
196
|
+
File.open(target, "w") do |f|
|
197
|
+
f.write(ERB.new(File.read(template), nil, "<>").result(binding))
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
# Javascript files
|
203
|
+
Dir[File.join(File.dirname(__FILE__), '..', 'javascripts', '*.js')].each do |jsfile|
|
204
|
+
filename = File.basename(jsfile)
|
205
|
+
target = "public/javascripts/#{filename}"
|
206
|
+
if File.exists?(target) and not @options.force
|
207
|
+
puts "Skipping existing file #{target}" if @options.verbose
|
208
|
+
else
|
209
|
+
puts "Writing file #{target}" if @options.verbose
|
210
|
+
FileUtils.mkdir_p(File.dirname(target))
|
211
|
+
FileUtils.cp jsfile, target
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
# Help
|
216
|
+
puts
|
217
|
+
puts(help.gsub(':singular', @options.singular).gsub(':plural', @options.plural))
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
# Create and run the application
|
223
|
+
app = Gadgeteer::App.new(ARGV, STDIN)
|
224
|
+
app.run
|
@@ -0,0 +1,230 @@
|
|
1
|
+
/*! Copyright (c) 2009 Virgo Systems Kft. (http://virgo.hu)
|
2
|
+
* Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
|
3
|
+
*
|
4
|
+
* Version: 1.0.2
|
5
|
+
* Requires opensocial-jQuery 0.5+
|
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
|
+
// All forms will submit through an ajax call
|
31
|
+
$('form').livequery('submit', function(e) {
|
32
|
+
e.preventDefault();
|
33
|
+
var form = $(this);
|
34
|
+
var action = form.attr('action');
|
35
|
+
var target = form.hasClass('silent') ? null : $.gadgeteer.defaultTarget;
|
36
|
+
$.ajax({
|
37
|
+
url: action.charAt(0) == '/' ? $.gadgeteer.host + action : action,
|
38
|
+
type: form.attr('method') || 'GET',
|
39
|
+
data: [$.param(form.formToArray()), $.param($.gadgeteer.viewer.osParams()), $.param($.gadgeteer.owner.osParams())].join("&"),
|
40
|
+
dataType: 'html',
|
41
|
+
auth: 'SIGNED',
|
42
|
+
target: target
|
43
|
+
});
|
44
|
+
});
|
45
|
+
}
|
46
|
+
|
47
|
+
// Setup ajax event callbacks
|
48
|
+
$(document).ajaxSend(function(e, request, settings) {
|
49
|
+
if (settings.target) {
|
50
|
+
// TODO: make this customizable by `loading` callback in options
|
51
|
+
$(settings.target).append($.gadgeteer.loadingElem());
|
52
|
+
}
|
53
|
+
}).ajaxSuccess(function(e, request, settings) {
|
54
|
+
$.gadgeteer.currentUrl = request.url;
|
55
|
+
if (settings.target) {
|
56
|
+
var html = request.responseText;
|
57
|
+
$(settings.target).html(html);
|
58
|
+
}
|
59
|
+
// !iframe
|
60
|
+
$(window).adjustHeight();
|
61
|
+
// Do another adjustHeight in 250ms just to be sure
|
62
|
+
setTimeout(function() {$(window).adjustHeight();}, 250);
|
63
|
+
}).ajaxError(function(e, request, settings, exception) {
|
64
|
+
console.log(request, settings, exception);
|
65
|
+
if (settings.target) {
|
66
|
+
var html = request.responseText;
|
67
|
+
$(settings.target).html(html);
|
68
|
+
}
|
69
|
+
// !iframe
|
70
|
+
$(window).adjustHeight();
|
71
|
+
// Do another adjustHeight in 250ms just to be sure
|
72
|
+
setTimeout(function() {$(window).adjustHeight();}, 250);
|
73
|
+
}).ajaxComplete(function(e, request, settings) {
|
74
|
+
if (request.status.toString().charAt(0) == '3') {
|
75
|
+
var href = request.getResponseHeader('Location') || request.getResponseHeader('location');
|
76
|
+
// hackish way to determine if we have an array (depends on the fact that the real href must be longer than 1 char)
|
77
|
+
if (!href.charAt) href = href[0];
|
78
|
+
$.ajax({
|
79
|
+
url: href.charAt(0) == '/' ? $.gadgeteer.host + href : href,
|
80
|
+
type: 'GET',
|
81
|
+
data: $.param($.gadgeteer.viewer.osParams()) + '&' + $.param($.gadgeteer.owner.osParams()),
|
82
|
+
dataType: 'html',
|
83
|
+
auth: settings.auth,
|
84
|
+
target: settings.target
|
85
|
+
});
|
86
|
+
}
|
87
|
+
});
|
88
|
+
|
89
|
+
// Wait for everything to load then call the callback
|
90
|
+
setTimeout(function() {
|
91
|
+
if ($.gadgeteer.viewer && $.gadgeteer.owner) {
|
92
|
+
// Navigate away if params tell so
|
93
|
+
var params = gadgets.views.getParams();
|
94
|
+
var navTo = params.navigateTo;
|
95
|
+
if (navTo) {
|
96
|
+
$.gadgeteer.simpleRequest(navTo, params.signedNavigate);
|
97
|
+
} else {
|
98
|
+
callback();
|
99
|
+
}
|
100
|
+
} else {
|
101
|
+
setTimeout(arguments.callee, 50);
|
102
|
+
}
|
103
|
+
}, 50);
|
104
|
+
|
105
|
+
} else { // if called with no arguments it means we're initializing
|
106
|
+
// Get information about the viewer and owner
|
107
|
+
$.getData('/people/@viewer/@self', function(data, status) {
|
108
|
+
$.gadgeteer.viewer = data[0];
|
109
|
+
$.gadgeteer.viewer.osParams = function() {return $.gadgeteer._osParams.call($.gadgeteer.viewer, 'viewer')};
|
110
|
+
});
|
111
|
+
$.getData('/people/@owner/@self', function(data, status) {
|
112
|
+
$.gadgeteer.owner = data[0];
|
113
|
+
$.gadgeteer.owner.osParams = function() {return $.gadgeteer._osParams.call($.gadgeteer.owner, 'owner')};
|
114
|
+
});
|
115
|
+
}
|
116
|
+
}
|
117
|
+
|
118
|
+
$.extend($.gadgeteer, {
|
119
|
+
_osParams: function(name) {
|
120
|
+
var params = {};
|
121
|
+
for (var attr in this) {
|
122
|
+
if (!$.isFunction(this[attr])) {
|
123
|
+
var underscore = attr.replace(/([A-Z])/, '_$1').toLowerCase();
|
124
|
+
params['os_'+name+'_'+underscore] = this[attr];
|
125
|
+
}
|
126
|
+
}
|
127
|
+
return params;
|
128
|
+
},
|
129
|
+
|
130
|
+
loadingElem: function() {
|
131
|
+
if ($.gadgeteer.LOADING_ELEM) return $.gadgeteer.LOADING_ELEM;
|
132
|
+
|
133
|
+
// TODO: make this customizable
|
134
|
+
var loading = $('#loading');
|
135
|
+
if (loading.length < 1) {
|
136
|
+
loading = $('<div id="loading">Az oldal tölt <span class="ellipses">…</span></div>');
|
137
|
+
}
|
138
|
+
return $.gadgeteer.LOADING_ELEM = loading;
|
139
|
+
},
|
140
|
+
|
141
|
+
simpleRequest: function(href, signed) {
|
142
|
+
var params = {}
|
143
|
+
if (href.indexOf('os_viewer_id') == -1) params.os_viewer_id = $.gadgeteer.viewer.id;
|
144
|
+
if (href.indexOf('os_owner_id') == -1) params.os_owner_id = $.gadgeteer.owner.id;
|
145
|
+
if (signed) {
|
146
|
+
params = $.extend(false, params, $.gadgeteer.viewer.osParams(), $.gadgeteer.owner.osParams());
|
147
|
+
}
|
148
|
+
$.ajax({
|
149
|
+
type: 'GET',
|
150
|
+
data: $.param(params),
|
151
|
+
url: href.charAt(0) == '/' ? $.gadgeteer.host + href : href,
|
152
|
+
dataType: 'html',
|
153
|
+
auth: signed && 'SIGNED',
|
154
|
+
target: $($.gadgeteer.defaultTarget)
|
155
|
+
});
|
156
|
+
},
|
157
|
+
|
158
|
+
regularRequest: function(e) {
|
159
|
+
// regular request (i.e. normal anchor click through) is a no-op
|
160
|
+
},
|
161
|
+
|
162
|
+
ajaxRequest: function(e) {
|
163
|
+
e.preventDefault();
|
164
|
+
var host = document.location.host;
|
165
|
+
var link = $(this);
|
166
|
+
var href = link.attr('href');
|
167
|
+
var _href = link[0].getAttribute('href');
|
168
|
+
|
169
|
+
//hack for IE href attr bug
|
170
|
+
if (_href.match(host)) {
|
171
|
+
var l = _href.search(host)+host.length;
|
172
|
+
href = _href.substring(l);
|
173
|
+
}
|
174
|
+
|
175
|
+
if (href.charAt(0) == '/') href = $.gadgeteer.host + href;
|
176
|
+
|
177
|
+
var params = {};
|
178
|
+
var method = link.hasClass('post') ? 'post' : link.hasClass('put') ? 'put' : link.hasClass('delete') ? 'delete' : 'get';
|
179
|
+
if (method != 'get') params._method = method;
|
180
|
+
if (link.hasClass('signed'))
|
181
|
+
params = $.extend(false, params, $.gadgeteer.viewer.osParams(), $.gadgeteer.owner.osParams());
|
182
|
+
else
|
183
|
+
params = $.extend(false, params, {os_viewer_id: $.gadgeteer.viewer.id, os_owner_id: $.gadgeteer.owner.id});
|
184
|
+
|
185
|
+
var target = link.hasClass('silent') ? null : $.gadgeteer.defaultTarget;
|
186
|
+
$.ajax({
|
187
|
+
type: method == 'get' ? 'GET' : 'POST',
|
188
|
+
url: href,
|
189
|
+
data: params,
|
190
|
+
dataType: target ? 'html' : null,
|
191
|
+
auth: link.hasClass('signed') ? 'SIGNED' : null,
|
192
|
+
target: target
|
193
|
+
});
|
194
|
+
},
|
195
|
+
|
196
|
+
navigateRequest: function(view, params, ownerId, e) {
|
197
|
+
e.preventDefault();
|
198
|
+
view = gadgets.views.getSupportedViews()[view];
|
199
|
+
gadgets.views.requestNavigateTo(view, params, ownerId);
|
200
|
+
},
|
201
|
+
|
202
|
+
handleLinkBehaviour: function(e) {
|
203
|
+
var link = $(this);
|
204
|
+
var matched = false;
|
205
|
+
$.each($.gadgeteer.linkBehaviours, function(behaviour, callback) {
|
206
|
+
var match;
|
207
|
+
if ($.isFunction(callback) && (match = callback.call(link, e))) {
|
208
|
+
var params = match === true ? [] : ($.isFunction(match.push) ? match : Array(match));
|
209
|
+
params.push(e);
|
210
|
+
//console.log('calling ', behaviour, ' link behaviour for ', link, ' with ', params);
|
211
|
+
var handler = behaviour+'Request';
|
212
|
+
handler = $.gadgeteer.linkBehaviours.handlers && $.gadgeteer.linkBehaviours.handlers[handler] || $.gadgeteer[handler];
|
213
|
+
handler.apply(link, params);
|
214
|
+
matched = true;
|
215
|
+
return false;
|
216
|
+
}
|
217
|
+
});
|
218
|
+
if (!matched) {
|
219
|
+
var def = $.gadgeteer.linkBehaviours.defaultBehavior || 'ajax';
|
220
|
+
//console.log('calling DEFAULT ', def, ' link behaviour for ', link, ' with ', e);
|
221
|
+
$.gadgeteer[def+'Request'].call(link, e);
|
222
|
+
}
|
223
|
+
}
|
224
|
+
|
225
|
+
});
|
226
|
+
|
227
|
+
// Initialize gadgeteer
|
228
|
+
$($.gadgeteer);
|
229
|
+
|
230
|
+
})(jQuery);
|