vidibus-xss 0.1.14 → 0.1.15

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.14
1
+ 0.1.15
@@ -8,7 +8,7 @@ module Vidibus
8
8
  extend ActiveSupport::Concern
9
9
 
10
10
  included do
11
- helper_method :url_for, :xss_request?, :fullpath_url
11
+ helper_method :url_for, :xss_request?, :fullpath_url, :render_xss_string, :extract_xss
12
12
  respond_to :html, :xss
13
13
  rescue_from ActionController::RoutingError, :with => :rescue_404
14
14
  end
@@ -140,13 +140,13 @@ module Vidibus
140
140
  resources
141
141
  end
142
142
 
143
- # Renders given content string to XSS hash of resources and content.
143
+ # Extracts XSS hash of resources and content from given content string.
144
144
  # If html content is given, the method tries to extract title,
145
145
  # stylesheets and javascripts from head and content from body.
146
146
  # TODO: Allow script blocks! Add them to body?
147
147
  # TODO: Allow style blocks?
148
148
  # TODO: Check for html content
149
- def render_to_xss(content)
149
+ def extract_xss(content)
150
150
  dom = Nokogiri::HTML(content)
151
151
  {
152
152
  :resources => extract_xss_javascripts(dom) + extract_xss_stylesheets(dom),
@@ -183,9 +183,18 @@ module Vidibus
183
183
  render_xss(:callback => data)
184
184
  end
185
185
 
186
+ # Controller method for rendering xss content.
187
+ def render_xss(options = {})
188
+ xss = render_xss_string(options)
189
+ xss_access_control_headers
190
+ self.content_type = Mime::XSS
191
+ self.status = 200 # force success status
192
+ self.response_body = xss
193
+ end
194
+
186
195
  # Main method for rendering XSS.
187
196
  # Renders given XSS resources and content to string and sets it as response_body.
188
- def render_xss(options = {})
197
+ def render_xss_string(options = {})
189
198
  resources = options.delete(:resources)
190
199
  content = options.delete(:content)
191
200
  path = options.delete(:get)
@@ -210,7 +219,7 @@ module Vidibus
210
219
 
211
220
  # render load invocations of XSS resources
212
221
  if resources and resources.any?
213
- xss << %(vidibus.loader.load(#{resources.to_json},'#{params[:scope]}');)
222
+ xss << %(xssLoader.load(#{resources.to_json},'#{params[:scope]}');)
214
223
  defer = true
215
224
  end
216
225
 
@@ -232,13 +241,9 @@ module Vidibus
232
241
  # wait until resources have been loaded, before rendering XSS content
233
242
  if defer
234
243
  function_name = "rx#{xss_random_string}"
235
- xss_content = %(var #{function_name}=function(){if(vidibus.loader.complete){#{xss_content}}else{window.setTimeout('#{function_name}()',100);}};#{function_name}();)
244
+ xss_content = %(var #{function_name}=function(){if(xssLoader.complete){#{xss_content}}else{window.setTimeout('#{function_name}()',100);}};#{function_name}();)
236
245
  end
237
246
  xss << xss_content
238
- xss_access_control_headers
239
- self.content_type = Mime::XSS
240
- self.status = 200 # force success status
241
- self.response_body = xss
242
247
  end
243
248
 
244
249
  # Generates random string for current cycle.
@@ -305,15 +310,21 @@ module Vidibus
305
310
 
306
311
  # embed xss.get
307
312
  if path = options[:path]
308
- content = render_to_string(:template => "layouts/#{get_layout(:xss)}")
309
- xss = render_to_xss(content)
313
+ template = options[:template]
314
+ if template === false
315
+ xss = {}
316
+ else
317
+ template ||= "layouts/#{get_layout(:xss)}"
318
+ content = render_to_string(:template => template)
319
+ xss = extract_xss(content)
320
+ end
310
321
  xss[:get] = "/#{path}"
311
322
  xss.delete(:content) # Ensure that not content will be embedded!
312
323
 
313
324
  # embed xss content
314
325
  else
315
326
  content = render_to_string(*args, &block)
316
- xss = render_to_xss(content)
327
+ xss = extract_xss(content)
317
328
  end
318
329
 
319
330
  render_xss(xss)
@@ -29,3 +29,54 @@ jQuery(function ($) {
29
29
  vidibus.csrf.data[vidibus.csrf.param] = encodeURIComponent(vidibus.csrf.token);
30
30
  }
31
31
  });
32
+
33
+
34
+ /**
35
+ * Implement ajax handler.
36
+ * This is the default handler provided in rails.js with some extensions.
37
+ */
38
+ $(function($) {
39
+ $.fn.extend({
40
+
41
+ /**
42
+ * Handles execution of remote calls firing overridable events along the way.
43
+ */
44
+ callAjax: function(url, method, data) {
45
+ var el = this,
46
+ method = method || el.attr('method') || el.attr('data-method') || 'GET',
47
+ dataType = el.attr('data-type') || 'script';
48
+ if (!url) url = el.attr('action') || el.attr('href') || el.attr('data-url');
49
+ if (url === undefined) {
50
+ throw "No URL specified for remote call (action or href must be present).";
51
+ } else {
52
+ if (el.triggerAndReturn('ajax:before')) {
53
+ data = data || el.is('form') ? el.serializeArray() : {};
54
+ if (method == 'delete') {
55
+ data['_method'] = method;
56
+ method = 'POST';
57
+ }
58
+ $.extend(data, vidibus.csrf.data());
59
+ $.ajax({
60
+ url: url,
61
+ data: data,
62
+ dataType: dataType,
63
+ type: method.toUpperCase(),
64
+ beforeSend: function(xhr) {
65
+ el.trigger('ajax:loading', xhr);
66
+ },
67
+ success: function(data, status, xhr) {
68
+ el.trigger('ajax:success', [data, status, xhr]);
69
+ },
70
+ complete: function(xhr) {
71
+ el.trigger('ajax:complete', xhr);
72
+ },
73
+ error: function(xhr, status, error) {
74
+ el.trigger('ajax:failure', [xhr, status, error]);
75
+ }
76
+ });
77
+ }
78
+ el.trigger('ajax:after');
79
+ }
80
+ }
81
+ });
82
+ });
@@ -1,13 +1,13 @@
1
1
  // Basic loader for stylesheets and javascripts.
2
- vidibus.loader = {
3
-
2
+ var xssLoader = {
3
+
4
4
  complete: true, // indicates that loading has been finished
5
5
  queue: [], // holds resources that are queued to load
6
6
  loading: undefined, // holds resource that is currently being loaded
7
7
  preloaded: undefined, // holds resources that are included in consumer base file
8
8
  loaded: {}, // holds resources that are currently loaded
9
9
  unused: {}, // holds resources that are loaded, but not required anymore
10
-
10
+
11
11
  /**
12
12
  * Load resources.
13
13
  */
@@ -19,98 +19,98 @@ vidibus.loader = {
19
19
  $(resources).each(function() {
20
20
  var resource = this,
21
21
  src = resource.src,
22
- name = vidibus.loader.resourceName(src);
23
-
22
+ name = xssLoader.resourceName(src);
23
+
24
24
  resource.name = name;
25
- resource.scopes = {}
25
+ resource.scopes = {};
26
26
  resource.scopes[scope] = true;
27
-
27
+
28
28
  // remove current file, because it is used
29
- delete vidibus.loader.unused[name];
29
+ delete xssLoader.unused[name];
30
30
 
31
31
  // skip files that have already been loaded
32
- if (vidibus.loader.loaded[name]) {
33
- vidibus.loader.loaded[name].scopes[scope] = true; // add current scope
32
+ if (xssLoader.loaded[name]) {
33
+ xssLoader.loaded[name].scopes[scope] = true; // add current scope
34
34
  return; // continue
35
- } else if (vidibus.loader.preloaded[name]) {
35
+ } else if (xssLoader.preloaded[name]) {
36
36
  return; // continue
37
37
  }
38
-
39
- vidibus.loader.loaded[name] = resource;
38
+
39
+ xssLoader.loaded[name] = resource;
40
40
  switch (resource.type) {
41
-
41
+
42
42
  // load css file directly
43
43
  case 'text/css':
44
- var element = document.createElement("link");
45
- element.rel = 'stylesheet';
46
- element.href = src;
44
+ var element = document.createElement("link");
45
+ element.rel = 'stylesheet';
46
+ element.href = src;
47
47
  element.media = resource.media || 'all';
48
48
  element.type = 'text/css';
49
- vidibus.loader.appendToHead(element);
49
+ xssLoader.appendToHead(element);
50
50
  break;
51
-
51
+
52
52
  // push script file to loading queue
53
53
  case 'text/javascript':
54
- vidibus.loader.queue.push(resource);
54
+ xssLoader.queue.push(resource);
55
55
  break;
56
-
57
- default: console.log('vidibus.loader.load: unsupported resource type: '+resource.type);
56
+
57
+ default: console.log('xssLoader.load: unsupported resource type: '+resource.type);
58
58
  }
59
59
  });
60
-
60
+
61
61
  this.loadQueue(true);
62
62
  this.unloadUnused(scope);
63
63
  },
64
-
64
+
65
65
  /**
66
66
  * Returns file name of resource.
67
67
  */
68
68
  resourceName: function(url) {
69
69
  return url.match(/\/([^\/\?]+)(\?.*)*$/)[1];
70
70
  },
71
-
71
+
72
72
  /**
73
73
  * Returns list of static resources.
74
74
  */
75
75
  initStaticResources: function() {
76
- if (vidibus.loader.preloaded == undefined) {
77
- vidibus.loader.preloaded = {};
76
+ if (xssLoader.preloaded === undefined) {
77
+ xssLoader.preloaded = {};
78
78
  var $resource, src, name;
79
79
  $('script[src],link[href]',$('head')).each(function() {
80
80
  $resource = $(this);
81
81
  src = $resource.attr('src') || $resource.attr('href');
82
- name = vidibus.loader.resourceName(src);
83
- vidibus.loader.preloaded[name] = src;
82
+ name = xssLoader.resourceName(src);
83
+ xssLoader.preloaded[name] = src;
84
84
  });
85
85
  }
86
86
  },
87
-
87
+
88
88
  /**
89
89
  * Loads resources in queue.
90
90
  */
91
91
  loadQueue: function(start) {
92
-
92
+
93
93
  // Reduce queue if this method is called as callback.
94
- if(start != true) {
95
- vidibus.loader.queue.shift();
94
+ if(start !== true) {
95
+ xssLoader.queue.shift();
96
96
  }
97
-
98
- var resource = vidibus.loader.queue[0];
99
-
97
+
98
+ var resource = xssLoader.queue[0];
99
+
100
100
  // return if file is currently loading
101
101
  if (resource) {
102
- if (resource == vidibus.loader.loading) {
102
+ if (resource === xssLoader.loading) {
103
103
  // console.log('CURRENTLY LOADING: '+resource.src);
104
104
  return;
105
105
  }
106
- vidibus.loader.loading = resource;
107
- vidibus.loader.loadScript(resource.src, vidibus.loader.loadQueue);
106
+ xssLoader.loading = resource;
107
+ xssLoader.loadScript(resource.src, xssLoader.loadQueue);
108
108
  } else {
109
- vidibus.loader.loading = undefined;
110
- vidibus.loader.complete = true;
109
+ xssLoader.loading = undefined;
110
+ xssLoader.complete = true;
111
111
  }
112
112
  },
113
-
113
+
114
114
  /**
115
115
  * Loads script src.
116
116
  */
@@ -121,66 +121,71 @@ vidibus.loader = {
121
121
  } else {
122
122
  // IE
123
123
  element.onreadystatechange = function() {
124
- if (this.readyState == 'loaded') callback.call(this);
125
- }
124
+ if (this.readyState === 'loaded') {
125
+ callback.call(this);
126
+ }
127
+ };
126
128
  }
127
129
  element.type = 'text/javascript';
128
130
  element.src = src;
129
- vidibus.loader.appendToHead(element);
131
+ xssLoader.appendToHead(element);
130
132
  element = null;
131
133
  },
132
-
134
+
133
135
  /**
134
136
  * Detects unused resources and removes them.
135
137
  */
136
138
  unloadUnused: function(scope) {
137
139
  var name, resources = [];
138
- for(name in vidibus.loader.unused) {
140
+ for(name in xssLoader.unused) {
141
+ if (xssLoader.unused.hasOwnProperty(name)) {
142
+ // Remove dependency for given scope.
143
+ if (xssLoader.unused[name].scopes[scope]) {
144
+ delete xssLoader.unused[name].scopes[scope];
145
+ }
139
146
 
140
- // Remove dependency for given scope.
141
- if (vidibus.loader.unused[name].scopes[scope]) {
142
- delete vidibus.loader.unused[name].scopes[scope];
143
- }
144
-
145
- // Unload resource if it has no dependencies left.
146
- if ($.isEmptyObject(vidibus.loader.unused[name].scopes)) {
147
- resources.push(vidibus.loader.unused[name]);
147
+ // Unload resource if it has no dependencies left.
148
+ if ($.isEmptyObject(xssLoader.unused[name].scopes)) {
149
+ resources.push(xssLoader.unused[name]);
150
+ }
148
151
  }
149
152
  }
150
- vidibus.loader.unload(resources);
151
- vidibus.loader.unused = {}
153
+ xssLoader.unload(resources);
154
+ xssLoader.unused = {};
152
155
  },
153
-
156
+
154
157
  /**
155
158
  * Removes resources given in list.
156
159
  */
157
160
  unload: function(resources) {
158
- var src, data, resource;
161
+ var src, resource;
159
162
  $(resources).each(function() {
160
163
  resource = this;
161
164
  src = resource.src;
162
-
163
- // console.log('REMOVE UNUSED RESOURCE: '+src);
164
-
165
165
  switch (resource.type) {
166
- case "text/css":
166
+ case "text/css":
167
167
  $('link[href="'+src+'"]').remove();
168
168
  break;
169
-
170
- case "text/javascript":
169
+
170
+ case "text/javascript":
171
171
  $('script[src="'+src+'"]').remove();
172
172
  break;
173
-
174
- default: console.log('vidibus.loader.unload: unsupported resource type: '+resource.type);
173
+
174
+ default: console.log('xssLoader.unload: unsupported resource type: '+resource.type);
175
175
  }
176
- delete vidibus.loader.loaded[resource.name];
176
+ delete xssLoader.loaded[resource.name];
177
177
  });
178
178
  },
179
-
179
+
180
180
  /**
181
181
  * Appends given element to document head.
182
182
  */
183
183
  appendToHead: function(element) {
184
- document.getElementsByTagName("head")[0].appendChild(element);
184
+ $("head")[0].appendChild(element);
185
185
  }
186
186
  };
187
+
188
+ // Maintain compatibility
189
+ if (typeof vidibus !== "undefined") {
190
+ vidibus.loader = xssLoader;
191
+ }
@@ -18,9 +18,14 @@ vidibus.xss = {
18
18
  initialized: {}, // holds true for every scope that has been initialized
19
19
  fileExtension: 'xss', // use 'xss' as file extension
20
20
  loadedUrls: {}, // store urls currently loaded in each scope
21
+ pathPrefix: '', // set a fixed prefix for all paths
22
+
23
+ ready: function() {
24
+ // TODO: implement real event handler
25
+ },
21
26
 
22
27
  /**
23
- * Detects scope of script block to be executed.
28
+ * Detects scope of script block to be executed.
24
29
  * Must be called from embedding page.
25
30
  */
26
31
  detectScope: function() {
@@ -30,50 +35,60 @@ vidibus.xss = {
30
35
  $detector.remove();
31
36
  return $scope;
32
37
  },
33
-
38
+
34
39
  /**
35
40
  * Usage:
36
- * vidibus.xss.embed('<div>Some HTML</div>', $('#scope'), 'http://host.url/');
41
+ * vidibus.xss.embed('<div>Some HTML</div>', $('#scope') [, ".some element"]);
37
42
  */
38
- embed: function(html, $scope, host) {
43
+ embed: function(html, $scope, selector) {
39
44
  html = this.transformPaths(html, $scope); // Transform local paths before embedding html into page!
40
- $scope.html(html);
45
+ if (selector) {
46
+ $(selector, $scope).html(html);
47
+ } else {
48
+ $scope.html(html);
49
+ }
41
50
  this.setUrls($scope);
42
51
  this.setActions($scope);
52
+ this.ready();
43
53
  },
44
-
54
+
45
55
  /**
46
56
  * Calls given path for given scope. If a third parameter is set to true,
47
57
  * the location will be loaded, even if it is currently loaded.
48
- *
58
+ *
49
59
  * Usage:
50
60
  * vidibus.xss.get('path', $('#scope') [, true]);
51
- *
61
+ *
52
62
  * If no host is provided, host of scope will be used.
53
63
  */
54
64
  get: function(path, $scope, reload) {
55
- // Escape query parts
65
+ // escape query parts
56
66
  path = path.replace("?", "%3F").replace("&", "%26").replace("=", "%3D");
57
67
 
68
+ // remove path prefix
69
+ if (typeof xssPathPrefix !== "undefined" && xssPathPrefix) {
70
+ path = path.replace(xssPathPrefix,'');
71
+ }
72
+
58
73
  var scopeId = $scope[0].id,
59
74
  params = scopeId+'='+this.getPath(path),
60
75
  keepCurrentLocation = this.initialized[scopeId] ? 0 : 1,
61
76
  location = $.param.fragment(String(document.location), params, keepCurrentLocation),
62
77
  reloadScope = {};
63
-
78
+
64
79
  this.initialized[scopeId] = true;
65
80
  window.location.href = location; // write history
66
81
  reloadScope[scopeId] = reload;
67
82
  this.loadUrl(location, reloadScope);
68
83
  },
69
-
84
+
70
85
  /**
71
86
  * Redirect to given path while forcing reloading.
72
87
  */
73
88
  redirect: function(path, $scope) {
74
- this.get(path, $scope, true)
89
+ this.get(path, $scope, true);
75
90
  },
76
-
91
+
77
92
  /**
78
93
  * Handles callback action.
79
94
  *
@@ -83,41 +98,41 @@ vidibus.xss = {
83
98
  * Accepts actions depending on status:
84
99
  * (redirect) to: Performs redirect to location.
85
100
  */
86
- callback: function(data, $scope) {
87
- if (data.status == 'redirect') {
101
+ callback: function(data, $scope) {
102
+ if (data.status === "redirect") {
88
103
  this.redirect(data.to, $scope);
89
104
  }
90
105
  },
91
-
106
+
92
107
  /**
93
108
  * Sets host for given scope.
94
109
  */
95
110
  setHost: function(host, $scope) {
96
111
  $scope.attr('data-host', host);
97
112
  },
98
-
113
+
99
114
  /**
100
115
  * Returns host for given scope.
101
116
  */
102
117
  getHost: function($scope) {
103
118
  return $scope.attr('data-host');
104
119
  },
105
-
120
+
106
121
  /**
107
122
  * Turns given path into an absolute url.
108
123
  */
109
124
  getUrl: function(path, host) {
110
- if (path.match(/https?:\/\//)) { return path }
125
+ if (path.match(/https?:\/\//)) { return path; }
111
126
  return host + path;
112
127
  },
113
-
128
+
114
129
  /**
115
130
  * Returns relative path from url.
116
131
  */
117
132
  getPath: function(url) {
118
- return url.replace(/https?:\/\/[^\/]+/,'')
133
+ return url.replace(/https?:\/\/[^\/]+/,'');
119
134
  },
120
-
135
+
121
136
  /**
122
137
  * Rewrites links to absolute urls.
123
138
  */
@@ -129,20 +144,20 @@ vidibus.xss = {
129
144
  var href = $(this).attr('href');
130
145
  $(this).attr('href', vidibus.xss.getUrl(href, host));
131
146
  });
132
-
147
+
133
148
  // Rewrite forms
134
149
  $('form[action]', $scope).each(function(e) {
135
150
  var action = $(this).attr('action');
136
151
  $(this).attr('href', vidibus.xss.getUrl(action, host));
137
152
  });
138
153
  },
139
-
154
+
140
155
  /**
141
156
  * Set xss actions for interactive elements.
142
157
  */
143
158
  setActions: function($scope) {
144
159
  var host = this.getHost($scope);
145
-
160
+
146
161
  // Set action for GET links
147
162
  // TODO: Allow links to be flagged as "external"
148
163
  $('a[href^='+host+']:not([data-method],[data-remote])', $scope).bind('click.xss', function(e) {
@@ -150,7 +165,7 @@ vidibus.xss = {
150
165
  vidibus.xss.get(href, $scope);
151
166
  e.preventDefault();
152
167
  });
153
-
168
+
154
169
  // Set action non-GET links
155
170
  // TODO: Remove bindings from links that match current host only: a[data-method][href^='+host+']:not([data-remote])
156
171
  $('a[data-method]:not([data-remote])').die('click').unbind('click'); // remove bindings
@@ -161,9 +176,9 @@ vidibus.xss = {
161
176
  $(this).callAjax(url);
162
177
  e.preventDefault();
163
178
  });
164
-
179
+
165
180
  // Set form action
166
- $('form[action]').die('submit').unbind('submit') // remove bindings
181
+ $('form[action]').die('submit').unbind('submit'); // remove bindings
167
182
  $('form[action][href^='+host+']', $scope).submit(function(e) {
168
183
  var $form = $(this),
169
184
  path = $form.attr('action');
@@ -172,7 +187,7 @@ vidibus.xss = {
172
187
  return false;
173
188
  });
174
189
  },
175
-
190
+
176
191
  /**
177
192
  * Modifies paths within given html string.
178
193
  * This method must be called before embedding html snippet into the page
@@ -180,13 +195,17 @@ vidibus.xss = {
180
195
  */
181
196
  transformPaths: function(html, $scope) {
182
197
  var match, url;
183
- while (match = html.match(/src="((?!http)[^"]+)"/)) {
198
+ while (true) {
199
+ match = html.match(/src="((?!http)[^"]+)"/);
200
+ if (!match) {
201
+ break;
202
+ }
184
203
  url = vidibus.xss.buildUrl(match[1], $scope);
185
- html = html.replace(match[0], 'src="'+url+'"')
204
+ html = html.replace(match[0], 'src="'+url+'"');
186
205
  }
187
206
  return html;
188
207
  },
189
-
208
+
190
209
  /**
191
210
  * Load XSS sources from given url.
192
211
  * If url is empty, the current location will be used.
@@ -194,24 +213,26 @@ vidibus.xss = {
194
213
  loadUrl: function(url, reload) {
195
214
  var scope, $scope, path, loaded, params = $.deparam.fragment();
196
215
  for(scope in params) {
197
- path = params[scope];
216
+ if (params.hasOwnProperty(scope)) {
217
+ path = params[scope];
198
218
 
199
- // don't reload locations that have already been loaded
200
- loaded = this.loadedUrls[scope];
201
- if((!reload || !reload[scope]) && loaded && loaded == path) {
202
- continue;
203
- }
219
+ // don't reload locations that have already been loaded
220
+ loaded = this.loadedUrls[scope];
221
+ if((!reload || !reload[scope]) && loaded && loaded === path) {
222
+ continue;
223
+ }
204
224
 
205
- $scope = $('#'+scope);
206
- if($scope[0] == undefined) {
207
- console.log('Scope not found: '+scope);
208
- } else {
209
- this.loadedUrls[scope] = path;
210
- this.loadData(path, $scope);
225
+ $scope = $('#'+scope);
226
+ if($scope[0] === undefined) {
227
+ console.log('Scope not found: '+scope);
228
+ } else {
229
+ this.loadedUrls[scope] = path;
230
+ this.loadData(path, $scope);
231
+ }
211
232
  }
212
233
  }
213
234
  },
214
-
235
+
215
236
  /**
216
237
  * Load relative path into given scope.
217
238
  * Transforms scope host and path into a XSS location.
@@ -225,7 +246,7 @@ vidibus.xss = {
225
246
  type: 'GET'
226
247
  });
227
248
  },
228
-
249
+
229
250
  /**
230
251
  * Tranforms local paths to absolute ones.
231
252
  */
@@ -236,27 +257,32 @@ vidibus.xss = {
236
257
  if(params) {
237
258
  params = params.split("&");
238
259
  } else {
239
- params = []
260
+ params = [];
261
+ }
262
+
263
+ // prepend path prefix
264
+ if (typeof xssPathPrefix !== "undefined" && xssPathPrefix && !path.match(xssPathPrefix)) {
265
+ path = xssPathPrefix + path;
240
266
  }
241
267
 
242
268
  var host = this.getHost($scope),
243
269
  scope = $scope.attr('id'),
244
- url = this.getUrl(path, host)
270
+ url = this.getUrl(path, host);
245
271
 
246
- if (!url.match(/\.[a-z]+((\?|\#).*)?$/)) url += '.xss';
247
- if (url.indexOf('.xss') > -1 && params.toString().indexOf('scope='+scope) == -1) {
272
+ if (!url.match(/\.[a-z]+((\?|\#).*)?$/)) { url += '.xss'; }
273
+ if (url.indexOf('.xss') > -1 && params.toString().indexOf('scope='+scope) === -1) {
248
274
  params.push('scope='+scope);
249
275
  }
250
-
276
+
251
277
  // add cache buster
252
278
  if (uncached) {
253
279
  var d = new Date();
254
280
  params.push(d.getTime());
255
281
  }
256
-
282
+
257
283
  // append params
258
284
  if (params.length) {
259
- if (url.indexOf('?') == -1) url += '?'
285
+ if (url.indexOf('?') === -1) { url += '?'; }
260
286
  url += params.join('&');
261
287
  }
262
288
 
@@ -266,13 +292,13 @@ vidibus.xss = {
266
292
 
267
293
  /**
268
294
  * Detect changes to document's location.
269
- *
295
+ *
270
296
  */
271
297
  $(function($){
272
-
298
+
273
299
  // Detect changes of document.location and trigger loading.
274
300
  $(window).bind('hashchange', function(e) {
275
- if (vidibus.loader.complete) {
301
+ if (xssLoader.complete) {
276
302
  vidibus.xss.loadUrl();
277
303
  }
278
304
  return false;
@@ -285,54 +311,10 @@ $(function($){
285
311
  });
286
312
 
287
313
  /**
288
- * Implement ajax handler.
289
- * This is the default handler provided in rails.js extended to accept delete method.
314
+ * Extend XHR
290
315
  */
291
316
  $(function($) {
292
- $.fn.extend({
293
-
294
- /**
295
- * Handles execution of remote calls firing overridable events along the way.
296
- */
297
- callAjax: function(url) {
298
- var el = this,
299
- method = el.attr('method') || el.attr('data-method') || 'GET',
300
- dataType = el.attr('data-type') || 'script';
301
- if (!url) url = el.attr('action') || el.attr('href');
302
- if (url === undefined) {
303
- throw "No URL specified for remote call (action or href must be present).";
304
- } else {
305
- if (el.triggerAndReturn('ajax:before')) {
306
- var data = el.is('form') ? el.serializeArray() : {};
307
- if (method == 'delete') {
308
- data['_method'] = method;
309
- method = 'POST';
310
- }
311
- $.extend(data, vidibus.csrf.data());
312
- $.ajax({
313
- url: url,
314
- data: data,
315
- dataType: dataType,
316
- type: method.toUpperCase(),
317
- beforeSend: function(xhr) {
318
- el.trigger('ajax:loading', xhr);
319
- },
320
- success: function(data, status, xhr) {
321
- el.trigger('ajax:success', [data, status, xhr]);
322
- },
323
- complete: function(xhr) {
324
- el.trigger('ajax:complete', xhr);
325
- },
326
- error: function(xhr, status, error) {
327
- el.trigger('ajax:failure', [xhr, status, error]);
328
- }
329
- });
330
- }
331
- el.trigger('ajax:after');
332
- }
333
- }
334
- });
335
-
317
+
336
318
  /**
337
319
  * Extend xhr object to send credentials and force XMLHttpRequest.
338
320
  */
@@ -341,17 +323,17 @@ $(function($) {
341
323
  try {
342
324
  xhr.withCredentials = "true";
343
325
  } catch(e) {
344
- alert('Cannot set xhr with credentials:\n'+e)
326
+ alert('Cannot set xhr with credentials:\n'+e);
345
327
  }
346
328
  };
347
-
329
+
348
330
  /**
349
331
  * Extends xhr on beforeSend by binding to Rails' ajax:loading event.
350
332
  */
351
333
  $("body").bind('ajax:loading', function(e, xhr) {
352
334
  extendXhr(xhr);
353
335
  });
354
-
336
+
355
337
  /**
356
338
  * Try to send xhr request withCredentials.
357
339
  * Unfortunately, this has to be set after the connection has been opened.
data/vidibus-xss.gemspec CHANGED
@@ -1,15 +1,15 @@
1
1
  # Generated by jeweler
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{vidibus-xss}
8
- s.version = "0.1.14"
8
+ s.version = "0.1.15"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Andre Pankratz"]
12
- s.date = %q{2010-10-05}
12
+ s.date = %q{2011-01-11}
13
13
  s.description = %q{Drop-in XSS support for remote applications.}
14
14
  s.email = %q{andre@vidibus.com}
15
15
  s.extra_rdoc_files = [
@@ -17,32 +17,30 @@ Gem::Specification.new do |s|
17
17
  ]
18
18
  s.files = [
19
19
  ".bundle/config",
20
- ".gitignore",
21
- ".rspec",
22
- "Gemfile",
23
- "Gemfile.lock",
24
- "MIT-LICENSE",
25
- "README.rdoc",
26
- "Rakefile",
27
- "VERSION",
28
- "app/controllers/xss_controller.rb",
29
- "config/routes.rb",
30
- "lib/vidibus-xss.rb",
31
- "lib/vidibus/xss.rb",
32
- "lib/vidibus/xss/extensions.rb",
33
- "lib/vidibus/xss/extensions/controller.rb",
34
- "lib/vidibus/xss/extensions/string.rb",
35
- "lib/vidibus/xss/extensions/view.rb",
36
- "lib/vidibus/xss/mime_type.rb",
37
- "public/javascripts/jquery.ba-bbq.js",
38
- "public/javascripts/vidibus.js",
39
- "public/javascripts/vidibus.loader.js",
40
- "public/javascripts/vidibus.xss.js",
41
- "spec/spec_helper.rb",
42
- "vidibus-xss.gemspec"
20
+ ".rspec",
21
+ "Gemfile",
22
+ "Gemfile.lock",
23
+ "MIT-LICENSE",
24
+ "README.rdoc",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "app/controllers/xss_controller.rb",
28
+ "config/routes.rb",
29
+ "lib/vidibus-xss.rb",
30
+ "lib/vidibus/xss.rb",
31
+ "lib/vidibus/xss/extensions.rb",
32
+ "lib/vidibus/xss/extensions/controller.rb",
33
+ "lib/vidibus/xss/extensions/string.rb",
34
+ "lib/vidibus/xss/extensions/view.rb",
35
+ "lib/vidibus/xss/mime_type.rb",
36
+ "public/javascripts/jquery.ba-bbq.js",
37
+ "public/javascripts/vidibus.js",
38
+ "public/javascripts/vidibus.loader.js",
39
+ "public/javascripts/vidibus.xss.js",
40
+ "spec/spec_helper.rb",
41
+ "vidibus-xss.gemspec"
43
42
  ]
44
43
  s.homepage = %q{http://github.com/vidibus/vidibus-xss}
45
- s.rdoc_options = ["--charset=UTF-8"]
46
44
  s.require_paths = ["lib"]
47
45
  s.rubygems_version = %q{1.3.7}
48
46
  s.summary = %q{Drop-in XSS support for remote applications.}
@@ -58,15 +56,42 @@ Gem::Specification.new do |s|
58
56
  s.add_runtime_dependency(%q<rails>, ["~> 3.0.0"])
59
57
  s.add_runtime_dependency(%q<nokogiri>, [">= 0"])
60
58
  s.add_runtime_dependency(%q<vidibus-routing_error>, [">= 0"])
59
+ s.add_runtime_dependency(%q<vidibus-uuid>, [">= 0"])
60
+ s.add_runtime_dependency(%q<jeweler>, [">= 0"])
61
+ s.add_runtime_dependency(%q<rake>, [">= 0"])
62
+ s.add_runtime_dependency(%q<rspec>, ["~> 2.0.0.beta.20"])
63
+ s.add_runtime_dependency(%q<rr>, [">= 0"])
64
+ s.add_runtime_dependency(%q<relevance-rcov>, [">= 0"])
65
+ s.add_runtime_dependency(%q<rails>, ["~> 3.0.0"])
66
+ s.add_runtime_dependency(%q<nokogiri>, [">= 0"])
67
+ s.add_runtime_dependency(%q<vidibus-routing_error>, [">= 0"])
61
68
  else
62
69
  s.add_dependency(%q<rails>, ["~> 3.0.0"])
63
70
  s.add_dependency(%q<nokogiri>, [">= 0"])
64
71
  s.add_dependency(%q<vidibus-routing_error>, [">= 0"])
72
+ s.add_dependency(%q<vidibus-uuid>, [">= 0"])
73
+ s.add_dependency(%q<jeweler>, [">= 0"])
74
+ s.add_dependency(%q<rake>, [">= 0"])
75
+ s.add_dependency(%q<rspec>, ["~> 2.0.0.beta.20"])
76
+ s.add_dependency(%q<rr>, [">= 0"])
77
+ s.add_dependency(%q<relevance-rcov>, [">= 0"])
78
+ s.add_dependency(%q<rails>, ["~> 3.0.0"])
79
+ s.add_dependency(%q<nokogiri>, [">= 0"])
80
+ s.add_dependency(%q<vidibus-routing_error>, [">= 0"])
65
81
  end
66
82
  else
67
83
  s.add_dependency(%q<rails>, ["~> 3.0.0"])
68
84
  s.add_dependency(%q<nokogiri>, [">= 0"])
69
85
  s.add_dependency(%q<vidibus-routing_error>, [">= 0"])
86
+ s.add_dependency(%q<vidibus-uuid>, [">= 0"])
87
+ s.add_dependency(%q<jeweler>, [">= 0"])
88
+ s.add_dependency(%q<rake>, [">= 0"])
89
+ s.add_dependency(%q<rspec>, ["~> 2.0.0.beta.20"])
90
+ s.add_dependency(%q<rr>, [">= 0"])
91
+ s.add_dependency(%q<relevance-rcov>, [">= 0"])
92
+ s.add_dependency(%q<rails>, ["~> 3.0.0"])
93
+ s.add_dependency(%q<nokogiri>, [">= 0"])
94
+ s.add_dependency(%q<vidibus-routing_error>, [">= 0"])
70
95
  end
71
96
  end
72
97
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vidibus-xss
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
4
+ hash: 5
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 14
10
- version: 0.1.14
9
+ - 15
10
+ version: 0.1.15
11
11
  platform: ruby
12
12
  authors:
13
13
  - Andre Pankratz
@@ -15,13 +15,14 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-10-05 00:00:00 +02:00
18
+ date: 2011-01-11 00:00:00 +01:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
- name: rails
22
+ type: :runtime
23
23
  prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
24
+ name: rails
25
+ version_requirements: &id001 !ruby/object:Gem::Requirement
25
26
  none: false
26
27
  requirements:
27
28
  - - ~>
@@ -32,12 +33,26 @@ dependencies:
32
33
  - 0
33
34
  - 0
34
35
  version: 3.0.0
35
- type: :runtime
36
- version_requirements: *id001
36
+ requirement: *id001
37
37
  - !ruby/object:Gem::Dependency
38
+ type: :runtime
39
+ prerelease: false
38
40
  name: nokogiri
41
+ version_requirements: &id002 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ hash: 3
47
+ segments:
48
+ - 0
49
+ version: "0"
50
+ requirement: *id002
51
+ - !ruby/object:Gem::Dependency
52
+ type: :runtime
39
53
  prerelease: false
40
- requirement: &id002 !ruby/object:Gem::Requirement
54
+ name: vidibus-routing_error
55
+ version_requirements: &id003 !ruby/object:Gem::Requirement
41
56
  none: false
42
57
  requirements:
43
58
  - - ">="
@@ -46,12 +61,86 @@ dependencies:
46
61
  segments:
47
62
  - 0
48
63
  version: "0"
64
+ requirement: *id003
65
+ - !ruby/object:Gem::Dependency
49
66
  type: :runtime
50
- version_requirements: *id002
67
+ prerelease: false
68
+ name: vidibus-uuid
69
+ version_requirements: &id004 !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ hash: 3
75
+ segments:
76
+ - 0
77
+ version: "0"
78
+ requirement: *id004
51
79
  - !ruby/object:Gem::Dependency
52
- name: vidibus-routing_error
80
+ type: :runtime
81
+ prerelease: false
82
+ name: jeweler
83
+ version_requirements: &id005 !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ hash: 3
89
+ segments:
90
+ - 0
91
+ version: "0"
92
+ requirement: *id005
93
+ - !ruby/object:Gem::Dependency
94
+ type: :runtime
95
+ prerelease: false
96
+ name: rake
97
+ version_requirements: &id006 !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ hash: 3
103
+ segments:
104
+ - 0
105
+ version: "0"
106
+ requirement: *id006
107
+ - !ruby/object:Gem::Dependency
108
+ type: :runtime
109
+ prerelease: false
110
+ name: rspec
111
+ version_requirements: &id007 !ruby/object:Gem::Requirement
112
+ none: false
113
+ requirements:
114
+ - - ~>
115
+ - !ruby/object:Gem::Version
116
+ hash: 62196427
117
+ segments:
118
+ - 2
119
+ - 0
120
+ - 0
121
+ - beta
122
+ - 20
123
+ version: 2.0.0.beta.20
124
+ requirement: *id007
125
+ - !ruby/object:Gem::Dependency
126
+ type: :runtime
127
+ prerelease: false
128
+ name: rr
129
+ version_requirements: &id008 !ruby/object:Gem::Requirement
130
+ none: false
131
+ requirements:
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ hash: 3
135
+ segments:
136
+ - 0
137
+ version: "0"
138
+ requirement: *id008
139
+ - !ruby/object:Gem::Dependency
140
+ type: :runtime
53
141
  prerelease: false
54
- requirement: &id003 !ruby/object:Gem::Requirement
142
+ name: relevance-rcov
143
+ version_requirements: &id009 !ruby/object:Gem::Requirement
55
144
  none: false
56
145
  requirements:
57
146
  - - ">="
@@ -60,8 +149,51 @@ dependencies:
60
149
  segments:
61
150
  - 0
62
151
  version: "0"
152
+ requirement: *id009
153
+ - !ruby/object:Gem::Dependency
63
154
  type: :runtime
64
- version_requirements: *id003
155
+ prerelease: false
156
+ name: rails
157
+ version_requirements: &id010 !ruby/object:Gem::Requirement
158
+ none: false
159
+ requirements:
160
+ - - ~>
161
+ - !ruby/object:Gem::Version
162
+ hash: 7
163
+ segments:
164
+ - 3
165
+ - 0
166
+ - 0
167
+ version: 3.0.0
168
+ requirement: *id010
169
+ - !ruby/object:Gem::Dependency
170
+ type: :runtime
171
+ prerelease: false
172
+ name: nokogiri
173
+ version_requirements: &id011 !ruby/object:Gem::Requirement
174
+ none: false
175
+ requirements:
176
+ - - ">="
177
+ - !ruby/object:Gem::Version
178
+ hash: 3
179
+ segments:
180
+ - 0
181
+ version: "0"
182
+ requirement: *id011
183
+ - !ruby/object:Gem::Dependency
184
+ type: :runtime
185
+ prerelease: false
186
+ name: vidibus-routing_error
187
+ version_requirements: &id012 !ruby/object:Gem::Requirement
188
+ none: false
189
+ requirements:
190
+ - - ">="
191
+ - !ruby/object:Gem::Version
192
+ hash: 3
193
+ segments:
194
+ - 0
195
+ version: "0"
196
+ requirement: *id012
65
197
  description: Drop-in XSS support for remote applications.
66
198
  email: andre@vidibus.com
67
199
  executables: []
@@ -72,7 +204,6 @@ extra_rdoc_files:
72
204
  - README.rdoc
73
205
  files:
74
206
  - .bundle/config
75
- - .gitignore
76
207
  - .rspec
77
208
  - Gemfile
78
209
  - Gemfile.lock
@@ -100,8 +231,8 @@ homepage: http://github.com/vidibus/vidibus-xss
100
231
  licenses: []
101
232
 
102
233
  post_install_message:
103
- rdoc_options:
104
- - --charset=UTF-8
234
+ rdoc_options: []
235
+
105
236
  require_paths:
106
237
  - lib
107
238
  required_ruby_version: !ruby/object:Gem::Requirement
data/.gitignore DELETED
@@ -1,21 +0,0 @@
1
- ## MAC OS
2
- .DS_Store
3
-
4
- ## TEXTMATE
5
- *.tmproj
6
- tmtags
7
-
8
- ## EMACS
9
- *~
10
- \#*
11
- .\#*
12
-
13
- ## VIM
14
- *.swp
15
-
16
- ## PROJECT::GENERAL
17
- coverage
18
- rdoc
19
- pkg
20
-
21
- ## PROJECT::SPECIFIC