xray-rails 0.1.23 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 43b754b678a67b95ac0d3894d4c21b147d760254
4
- data.tar.gz: 4913f797e357d7398bb19c701fa03d79f17d5cbb
3
+ metadata.gz: af26d9471fb39cf9697c4142f11d1218b282949f
4
+ data.tar.gz: 2dec43a0a579d6cce8a8159c3b97cb5a42d6168d
5
5
  SHA512:
6
- metadata.gz: 721030f3a4b17b65c520aa0add7544d4fad43493b8d495681d93f48c90c6e5a42694f54a6e747d38255baf165808689f6cc60d1ad3c7e93289dbc23fd943c135
7
- data.tar.gz: aa9b458338cb265942693b3cca64ccd9a2dfbbe26ba7c9b9a3309d0096e38762843fb45f59f3621631b15e82a24f9fec7521706fac26dd04aa23ec50bed2e0e4
6
+ metadata.gz: 36432e25ecbaa3cebacb6d6942de25567e7af1a082baea0f3946c821a2260aea6f53d436c4109f7428051db2c080daacf68a9f1821895dd37d757bc0f74725aa
7
+ data.tar.gz: ac7a9ef35f340e7e039d3f0a438c69e7b17e0de362f07a52af7c15e9326fa431cfd0bcc04987aeaab92dda88b5d51cf3da12992e7e99c54dac8b2276378921c6
data/README.md CHANGED
@@ -6,7 +6,7 @@ Xray-rails
6
6
 
7
7
  ### Reveal your UI's bones
8
8
 
9
- The dev tools available to web developers in modern browsers are great. Many of us can't remember what life was like before "Inspect Element". But what we see in the compiled output sent to our browser is often the wrong level of detail - what about visualizing the higher level components of your UI? Controllers, templates, partials, Backbone views, etc.
9
+ The dev tools available to web developers in modern browsers are great. Many of us can't remember what life was like before "Inspect Element". But what we see in the compiled output sent to our browser is often the wrong level of detail - what about visualizing the higher level components of your UI? Controllers, view templates, partials, JS templates, etc.
10
10
 
11
11
  Xray is the missing link between the browser and your app code. Press **cmd+shift+x** (Mac) or **ctrl+shift+x** to reveal an overlay of the files that rendered your UI, and click anything to open the file in your editor. [See Xray in action](http://f.cl.ly/items/1A0o3y1y3Q13103V3F1l/xray-rails-large.gif).
12
12
 
@@ -19,12 +19,11 @@ Xray is intended for Rails 3.1+ and Ruby 1.9+.
19
19
  So far, Xray can reveal:
20
20
 
21
21
  * Rails views and partials
22
- * Backbone View instances if using the asset pipeline
23
22
  * Javascript templates if using the asset pipeline with the .jst extension
24
23
 
25
24
  ## Installation
26
25
 
27
- Xray depends on **jQuery**. Backbone is optional.
26
+ Xray depends on **jQuery**.
28
27
 
29
28
  This gem should only be present during development. Add it to your Gemfile:
30
29
 
@@ -44,20 +43,15 @@ Restart your app, visit it in your browser, and press **cmd+shift+x** (Mac) or *
44
43
 
45
44
  #### Note about `config.assets.debug`
46
45
 
47
- For Xray to insert itself into your views automatically, `config.assets.debug = true` (Rails' default) must be set in development.rb. If you disabled this because of slow assets in Rails 3.2.13, [try this monkey patch instead](http://stackoverflow.com/a/15520932/24848) in an initializer.
46
+ By default, Xray will insert itself into your views automatically. To do this, `config.assets.debug = true` (Rails' default) must be set in development.rb.
48
47
 
49
48
  Otherwise, you can insert Xray's scripts yourself, for example like so in application.js:
50
49
 
51
50
  ```js
52
51
  //= require jquery
53
52
  //= require xray
54
- ...
55
- //= require backbone
56
- //= require xray-backbone
57
53
  ```
58
54
 
59
- Backbone support via `xray-backbone` is optional.
60
-
61
55
  ## Configuration
62
56
 
63
57
  By default, Xray will check a few environment variables to determine
@@ -80,7 +74,6 @@ For something more complex, use the `$file` placeholder.
80
74
  ## How this works
81
75
 
82
76
  * At run time, HTML responses from Rails are wrapped with HTML comments containing filepath info.
83
- * Additionally, JS templates and Backbone view constructors are modified during asset compilation.
84
77
  * A middleware inserts `xray.js`, `xray.css`, and the Xray bar into all successful HTML response bodies.
85
78
  * When the overlay is shown, `xray.js` examines the inserted filepath info to build the overlay.
86
79
 
@@ -0,0 +1,471 @@
1
+ // Generated by CoffeeScript 1.9.2
2
+ (function() {
3
+ var $, MAX_ZINDEX, util,
4
+ hasProp = {}.hasOwnProperty,
5
+ bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
6
+ extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
7
+
8
+ window.Xray = {};
9
+
10
+ if (!($ = window.jQuery)) {
11
+ return;
12
+ }
13
+
14
+ MAX_ZINDEX = 2147483647;
15
+
16
+ Xray.init = (function() {
17
+ var is_mac;
18
+ if (Xray.initialized) {
19
+ return;
20
+ }
21
+ Xray.initialized = true;
22
+ is_mac = navigator.platform.toUpperCase().indexOf('MAC') !== -1;
23
+ $(document).keydown(function(e) {
24
+ if ((is_mac && e.metaKey || !is_mac && e.ctrlKey) && e.shiftKey && e.keyCode === 88) {
25
+ if (Xray.isShowing) {
26
+ Xray.hide();
27
+ } else {
28
+ Xray.show();
29
+ }
30
+ }
31
+ if (Xray.isShowing && e.keyCode === 27) {
32
+ return Xray.hide();
33
+ }
34
+ });
35
+ return $(function() {
36
+ new Xray.Overlay;
37
+ Xray.findTemplates();
38
+ return typeof console !== "undefined" && console !== null ? console.log("Ready to Xray. Press " + (is_mac ? 'cmd+shift+x' : 'ctrl+shift+x') + " to scan your UI.") : void 0;
39
+ });
40
+ })();
41
+
42
+ Xray.specimens = function() {
43
+ return Xray.ViewSpecimen.all.concat(Xray.TemplateSpecimen.all);
44
+ };
45
+
46
+ Xray.constructorInfo = function(constructor) {
47
+ var func, info, ref;
48
+ if (window.XrayPaths) {
49
+ ref = window.XrayPaths;
50
+ for (info in ref) {
51
+ if (!hasProp.call(ref, info)) continue;
52
+ func = ref[info];
53
+ if (func === constructor) {
54
+ return JSON.parse(info);
55
+ }
56
+ }
57
+ }
58
+ return null;
59
+ };
60
+
61
+ Xray.findTemplates = function() {
62
+ return util.bm('findTemplates', function() {
63
+ var $templateContents, _, comment, comments, el, i, id, len, path, ref, results;
64
+ comments = $('*:not(iframe,script)').contents().filter(function() {
65
+ return this.nodeType === 8 && this.data.slice(0, 10) === "XRAY START";
66
+ });
67
+ results = [];
68
+ for (i = 0, len = comments.length; i < len; i++) {
69
+ comment = comments[i];
70
+ ref = comment.data.match(/^XRAY START (\d+) (.*)$/), _ = ref[0], id = ref[1], path = ref[2];
71
+ $templateContents = new jQuery;
72
+ el = comment.nextSibling;
73
+ while (!(!el || (el.nodeType === 8 && el.data === ("XRAY END " + id)))) {
74
+ if (el.nodeType === 1 && el.tagName !== 'SCRIPT') {
75
+ $templateContents.push(el);
76
+ }
77
+ el = el.nextSibling;
78
+ }
79
+ if ((el != null ? el.nodeType : void 0) === 8) {
80
+ el.parentNode.removeChild(el);
81
+ }
82
+ comment.parentNode.removeChild(comment);
83
+ results.push(Xray.TemplateSpecimen.add($templateContents, {
84
+ name: path.split('/').slice(-1)[0],
85
+ path: path
86
+ }));
87
+ }
88
+ return results;
89
+ });
90
+ };
91
+
92
+ Xray.open = function(path) {
93
+ return $.ajax({
94
+ url: "/_xray/open?path=" + path
95
+ });
96
+ };
97
+
98
+ Xray.show = function(type) {
99
+ if (type == null) {
100
+ type = null;
101
+ }
102
+ return Xray.Overlay.instance().show(type);
103
+ };
104
+
105
+ Xray.hide = function() {
106
+ return Xray.Overlay.instance().hide();
107
+ };
108
+
109
+ Xray.toggleSettings = function() {
110
+ return Xray.Overlay.instance().settings.toggle();
111
+ };
112
+
113
+ Xray.Specimen = (function() {
114
+ Specimen.add = function(el, info) {
115
+ if (info == null) {
116
+ info = {};
117
+ }
118
+ return this.all.push(new this(el, info));
119
+ };
120
+
121
+ Specimen.remove = function(el) {
122
+ var ref;
123
+ return (ref = this.find(el)) != null ? ref.remove() : void 0;
124
+ };
125
+
126
+ Specimen.find = function(el) {
127
+ var i, len, ref, specimen;
128
+ if (el instanceof jQuery) {
129
+ el = el[0];
130
+ }
131
+ ref = this.all;
132
+ for (i = 0, len = ref.length; i < len; i++) {
133
+ specimen = ref[i];
134
+ if (specimen.el === el) {
135
+ return specimen;
136
+ }
137
+ }
138
+ return null;
139
+ };
140
+
141
+ Specimen.reset = function() {
142
+ return this.all = [];
143
+ };
144
+
145
+ function Specimen(contents, info) {
146
+ if (info == null) {
147
+ info = {};
148
+ }
149
+ this.makeLabel = bind(this.makeLabel, this);
150
+ this.el = contents instanceof jQuery ? contents[0] : contents;
151
+ this.$contents = $(contents);
152
+ this.name = info.name;
153
+ this.path = info.path;
154
+ }
155
+
156
+ Specimen.prototype.remove = function() {
157
+ var idx;
158
+ idx = this.constructor.all.indexOf(this);
159
+ if (idx !== -1) {
160
+ return this.constructor.all.splice(idx, 1);
161
+ }
162
+ };
163
+
164
+ Specimen.prototype.isVisible = function() {
165
+ return this.$contents.length && this.$contents.is(':visible');
166
+ };
167
+
168
+ Specimen.prototype.makeBox = function() {
169
+ this.bounds = util.computeBoundingBox(this.$contents);
170
+ this.$box = $("<div class='xray-specimen " + this.constructor.name + "'>").css(this.bounds).attr('title', this.path);
171
+ if (this.$contents.css('position') === 'fixed') {
172
+ this.$box.css({
173
+ position: 'fixed',
174
+ top: this.$contents.css('top'),
175
+ left: this.$contents.css('left')
176
+ });
177
+ }
178
+ this.$box.click((function(_this) {
179
+ return function() {
180
+ return Xray.open(_this.path);
181
+ };
182
+ })(this));
183
+ return this.$box.append(this.makeLabel);
184
+ };
185
+
186
+ Specimen.prototype.makeLabel = function() {
187
+ return $("<div class='xray-specimen-handle " + this.constructor.name + "'>").append(this.name);
188
+ };
189
+
190
+ return Specimen;
191
+
192
+ })();
193
+
194
+ Xray.ViewSpecimen = (function(superClass) {
195
+ extend(ViewSpecimen, superClass);
196
+
197
+ function ViewSpecimen() {
198
+ return ViewSpecimen.__super__.constructor.apply(this, arguments);
199
+ }
200
+
201
+ ViewSpecimen.all = [];
202
+
203
+ return ViewSpecimen;
204
+
205
+ })(Xray.Specimen);
206
+
207
+ Xray.TemplateSpecimen = (function(superClass) {
208
+ extend(TemplateSpecimen, superClass);
209
+
210
+ function TemplateSpecimen() {
211
+ return TemplateSpecimen.__super__.constructor.apply(this, arguments);
212
+ }
213
+
214
+ TemplateSpecimen.all = [];
215
+
216
+ return TemplateSpecimen;
217
+
218
+ })(Xray.Specimen);
219
+
220
+ Xray.Overlay = (function() {
221
+ Overlay.instance = function() {
222
+ return this.singletonInstance || (this.singletonInstance = new this);
223
+ };
224
+
225
+ function Overlay() {
226
+ Xray.Overlay.singletonInstance = this;
227
+ this.bar = new Xray.Bar('#xray-bar');
228
+ this.settings = new Xray.Settings('#xray-settings');
229
+ this.shownBoxes = [];
230
+ this.$overlay = $('<div id="xray-overlay">');
231
+ this.$overlay.click((function(_this) {
232
+ return function() {
233
+ return _this.hide();
234
+ };
235
+ })(this));
236
+ }
237
+
238
+ Overlay.prototype.show = function(type) {
239
+ if (type == null) {
240
+ type = null;
241
+ }
242
+ this.reset();
243
+ Xray.isShowing = true;
244
+ return util.bm('show', (function(_this) {
245
+ return function() {
246
+ var element, i, len, results, specimens;
247
+ _this.bar.$el().find('#xray-bar-togglers .xray-bar-btn').removeClass('active');
248
+ if (!_this.$overlay.is(':visible')) {
249
+ $('body').append(_this.$overlay);
250
+ _this.bar.show();
251
+ }
252
+ switch (type) {
253
+ case 'templates':
254
+ Xray.findTemplates();
255
+ specimens = Xray.TemplateSpecimen.all;
256
+ _this.bar.$el().find('.xray-bar-templates-toggler').addClass('active');
257
+ break;
258
+ case 'views':
259
+ specimens = Xray.ViewSpecimen.all;
260
+ _this.bar.$el().find('.xray-bar-views-toggler').addClass('active');
261
+ break;
262
+ default:
263
+ Xray.findTemplates();
264
+ specimens = Xray.specimens();
265
+ _this.bar.$el().find('.xray-bar-all-toggler').addClass('active');
266
+ }
267
+ results = [];
268
+ for (i = 0, len = specimens.length; i < len; i++) {
269
+ element = specimens[i];
270
+ if (!element.isVisible()) {
271
+ continue;
272
+ }
273
+ element.makeBox();
274
+ element.$box.css({
275
+ zIndex: Math.ceil(MAX_ZINDEX * 0.9 + element.bounds.top + element.bounds.left)
276
+ });
277
+ _this.shownBoxes.push(element.$box);
278
+ results.push($('body').append(element.$box));
279
+ }
280
+ return results;
281
+ };
282
+ })(this));
283
+ };
284
+
285
+ Overlay.prototype.reset = function() {
286
+ var $box, i, len, ref;
287
+ ref = this.shownBoxes;
288
+ for (i = 0, len = ref.length; i < len; i++) {
289
+ $box = ref[i];
290
+ $box.remove();
291
+ }
292
+ return this.shownBoxes = [];
293
+ };
294
+
295
+ Overlay.prototype.hide = function() {
296
+ Xray.isShowing = false;
297
+ this.$overlay.detach();
298
+ this.reset();
299
+ return this.bar.hide();
300
+ };
301
+
302
+ return Overlay;
303
+
304
+ })();
305
+
306
+ Xray.Bar = (function() {
307
+ function Bar(el) {
308
+ this.el = el;
309
+ }
310
+
311
+ Bar.prototype.$el = function() {
312
+ if ((this.$el_memo != null) && $.contains(window.document, this.$el_memo[0])) {
313
+ return this.$el_memo;
314
+ }
315
+ this.$el_memo = $(this.el);
316
+ this.$el_memo.css({
317
+ zIndex: MAX_ZINDEX
318
+ });
319
+ this.$el_memo.find('#xray-bar-controller-path .xray-bar-btn').click(function() {
320
+ return Xray.open($(this).attr('data-path'));
321
+ });
322
+ this.$el_memo.find('.xray-bar-all-toggler').click(function() {
323
+ return Xray.show();
324
+ });
325
+ this.$el_memo.find('.xray-bar-templates-toggler').click(function() {
326
+ return Xray.show('templates');
327
+ });
328
+ this.$el_memo.find('.xray-bar-views-toggler').click(function() {
329
+ return Xray.show('views');
330
+ });
331
+ this.$el_memo.find('.xray-bar-settings-btn').click(function() {
332
+ return Xray.toggleSettings();
333
+ });
334
+ return this.$el_memo;
335
+ };
336
+
337
+ Bar.prototype.show = function() {
338
+ this.$el().show();
339
+ this.originalPadding = parseInt($('html').css('padding-bottom'));
340
+ if (this.originalPadding < 40) {
341
+ return $('html').css({
342
+ paddingBottom: 40
343
+ });
344
+ }
345
+ };
346
+
347
+ Bar.prototype.hide = function() {
348
+ this.$el().hide();
349
+ return $('html').css({
350
+ paddingBottom: this.originalPadding
351
+ });
352
+ };
353
+
354
+ return Bar;
355
+
356
+ })();
357
+
358
+ Xray.Settings = (function() {
359
+ function Settings(el) {
360
+ this.displayUpdateMsg = bind(this.displayUpdateMsg, this);
361
+ this.save = bind(this.save, this);
362
+ this.toggle = bind(this.toggle, this);
363
+ this.el = el;
364
+ }
365
+
366
+ Settings.prototype.$el = function() {
367
+ if ((this.$el_memo != null) && $.contains(window.document, this.$el_memo[0])) {
368
+ return this.$el_memo;
369
+ }
370
+ this.$el_memo = $(this.el);
371
+ this.$el_memo.find('form').submit(this.save);
372
+ return this.$el_memo;
373
+ };
374
+
375
+ Settings.prototype.toggle = function() {
376
+ return this.$el().toggle();
377
+ };
378
+
379
+ Settings.prototype.save = function(e) {
380
+ var editor;
381
+ e.preventDefault();
382
+ editor = this.$el().find('#xray-editor-input').val();
383
+ return $.ajax({
384
+ url: '/_xray/config',
385
+ type: 'POST',
386
+ data: {
387
+ editor: editor
388
+ },
389
+ success: (function(_this) {
390
+ return function() {
391
+ return _this.displayUpdateMsg(true);
392
+ };
393
+ })(this),
394
+ error: (function(_this) {
395
+ return function() {
396
+ return _this.displayUpdateMsg(false);
397
+ };
398
+ })(this)
399
+ });
400
+ };
401
+
402
+ Settings.prototype.displayUpdateMsg = function(success) {
403
+ var $msg;
404
+ if (success) {
405
+ $msg = $("<span class='xray-settings-success xray-settings-update-msg'>Success!</span>");
406
+ } else {
407
+ $msg = $("<span class='xray-settings-error xray-settings-update-msg'>Uh oh, something went wrong!</span>");
408
+ }
409
+ this.$el().append($msg);
410
+ return $msg.delay(2000).fadeOut(500, (function(_this) {
411
+ return function() {
412
+ $msg.remove();
413
+ return _this.toggle();
414
+ };
415
+ })(this));
416
+ };
417
+
418
+ return Settings;
419
+
420
+ })();
421
+
422
+ util = {
423
+ bm: function(name, fn) {
424
+ var result, time;
425
+ time = new Date;
426
+ result = fn();
427
+ return result;
428
+ },
429
+ computeBoundingBox: function($contents) {
430
+ var $el, boxFrame, el, frame, i, len;
431
+ if ($contents.length === 1 && $contents.height() <= 0) {
432
+ return util.computeBoundingBox($contents.children());
433
+ }
434
+ boxFrame = {
435
+ top: Number.POSITIVE_INFINITY,
436
+ left: Number.POSITIVE_INFINITY,
437
+ right: Number.NEGATIVE_INFINITY,
438
+ bottom: Number.NEGATIVE_INFINITY
439
+ };
440
+ for (i = 0, len = $contents.length; i < len; i++) {
441
+ el = $contents[i];
442
+ $el = $(el);
443
+ if (!$el.is(':visible')) {
444
+ continue;
445
+ }
446
+ frame = $el.offset();
447
+ frame.right = frame.left + $el.outerWidth();
448
+ frame.bottom = frame.top + $el.outerHeight();
449
+ if (frame.top < boxFrame.top) {
450
+ boxFrame.top = frame.top;
451
+ }
452
+ if (frame.left < boxFrame.left) {
453
+ boxFrame.left = frame.left;
454
+ }
455
+ if (frame.right > boxFrame.right) {
456
+ boxFrame.right = frame.right;
457
+ }
458
+ if (frame.bottom > boxFrame.bottom) {
459
+ boxFrame.bottom = frame.bottom;
460
+ }
461
+ }
462
+ return {
463
+ left: boxFrame.left,
464
+ top: boxFrame.top,
465
+ width: boxFrame.right - boxFrame.left,
466
+ height: boxFrame.bottom - boxFrame.top
467
+ };
468
+ }
469
+ };
470
+
471
+ }).call(this);
@@ -17,52 +17,6 @@ module Xray
17
17
  Thread.current[:request_info] ||= {}
18
18
  end
19
19
 
20
- # Patterns for the kind of JS constructors Xray is interested in knowing the
21
- # filepath of. Unforunately, these patterns will result in a lot of false
22
- # positives, because we can't only match direct Backbone.View subclasses -
23
- # the app's JS may have a more complex class hierarchy than that.
24
- CONSTRUCTOR_PATTERNS = [
25
- '(?!jQuery|_)[\w\.]+\.extend\({', # Match uses of extend(), excluding jQuery and underscore
26
- '\(function\(_super\) {' # Coffeescript-generated constructors
27
- ]
28
-
29
- # Example matches:
30
- # MyView = Backbone.View.extend({ ...
31
- # Foo.MyView = Backbone.View.extend({ ...
32
- # MyView = (function(_super) { ...
33
- #
34
- # Captures:
35
- # $1 = space before the constructor
36
- # $2 = the constructor's name
37
- # $3 = the beginning of the constructor function
38
- CONSTRUCTOR_REGEX = /^( *)([\w\.]+) *= *(#{CONSTRUCTOR_PATTERNS.join('|')})/
39
-
40
- # Returns augmented JS source where constructors Xray wants to know the
41
- # filepath of are captured in such a way that at runtime, xray.js can look
42
- # up a view constructor's filepath and name.
43
- #
44
- # This:
45
- # MyView = Backbone.View.extend({ ...
46
- #
47
- # Becomes:
48
- # MyView = (window.XrayPaths||(window.XrayPaths={}))['{"name":"MyView","path":"/path/to/file.js"}'] = Backbone.View.extend({ ...
49
- #
50
- # A goal here was to not add any new lines to the source so as not to throw
51
- # off line numbers if an exception is thrown, hence the odd pattern of
52
- # abusing an object set operation in a multiple assignment.
53
- #
54
- # TODO: This is simple and gets the job done, but is a bit ridiculous.
55
- # I've also seen this appear in stack traces :( Would love to find a
56
- # way to do this without actually writing to the files.
57
- def self.augment_js(source, path)
58
- source.gsub(CONSTRUCTOR_REGEX) do
59
- space, class_name, func = $1, $2, $3
60
- info = {name: class_name, path: path.to_s}
61
- xray = "(window.XrayPaths||(window.XrayPaths={}))['#{info.to_json}']"
62
- "#{space}#{class_name} = #{xray} = #{func}"
63
- end
64
- end
65
-
66
20
  # Returns augmented HTML where the source is simply wrapped in an HTML
67
21
  # comment with filepath info. Xray.js uses these comments to associate
68
22
  # elements with the templates that rendered them.
@@ -10,24 +10,12 @@ module Xray
10
10
  app.middleware.use Xray::Middleware
11
11
 
12
12
  # Required by Rails 4.1
13
- app.config.assets.precompile += %w(xray.js xray-backbone.js xray.css)
13
+ app.config.assets.precompile += %w(xray.js xray.css)
14
14
  end
15
15
 
16
16
  config.after_initialize do |app|
17
17
  ensure_asset_pipeline_enabled! app
18
18
 
19
- # Register as a Sprockets processor to augment JS files, including
20
- # compiled coffeescript, with filepath information. See
21
- # `Xray.augment_js` for details.
22
- app.assets.register_postprocessor 'application/javascript', :xray do |context, data|
23
- path = context.pathname.to_s
24
- if path =~ /^#{app.root}.+\.(js|coffee)(\.|$)/
25
- Xray.augment_js(data, path)
26
- else
27
- data
28
- end
29
- end
30
-
31
19
  # Monkey patch ActionView::Template to augment server-side templates
32
20
  # with filepath information. See `Xray.augment_template` for details.
33
21
  ActionView::Template.class_eval do
@@ -52,16 +40,40 @@ module Xray
52
40
  alias_method_chain :render, :xray
53
41
  end
54
42
 
55
- # Augment JS templates
56
- app.assets.register_preprocessor 'application/javascript', :xray do |context, source|
57
- path = context.pathname.to_s
58
- if path =~ /^#{app.root}.+\.(jst)(\.|$)/
59
- Xray.augment_template(source, path)
60
- else
61
- source
43
+ # Sprockets preprocessor interface which supports all versions of Sprockets.
44
+ # See: https://github.com/rails/sprockets/blob/master/guides/extending_sprockets.md#supporting-all-versions-of-sprockets-in-processors
45
+ class JavascriptPreprocessor
46
+ def initialize(filename, &block)
47
+ @filename = filename
48
+ @source = block.call
49
+ end
50
+
51
+ def render(context, empty_hash_wtf)
52
+ self.class.run(@filename, @source, context)
53
+ end
54
+
55
+ def self.run(filename, source, context)
56
+ path = context.pathname.to_s
57
+ if path =~ /^#{Rails.root}.+\.(jst)(\.|$)/
58
+ Xray.augment_template(source, path)
59
+ else
60
+ source
61
+ end
62
+ end
63
+
64
+ def self.call(input)
65
+ filename = input[:filename]
66
+ source = input[:data]
67
+ context = input[:environment].context_class.new(input)
68
+
69
+ result = run(filename, source, context)
70
+ context.metadata.merge(data: result)
62
71
  end
63
72
  end
64
73
 
74
+ # Augment JS templates
75
+ app.assets.register_preprocessor 'application/javascript', JavascriptPreprocessor
76
+
65
77
  # This event is called near the beginning of a request cycle. We use it to
66
78
  # collect information about the controller and action that is responding, for
67
79
  # display in the Xray bar.
@@ -4,9 +4,9 @@ module Xray
4
4
  OPEN_PATH = '/_xray/open'
5
5
  UPDATE_CONFIG_PATH = '/_xray/config'
6
6
 
7
- # This middleware is responsible for injecting xray.js, xray-backbone.js, and
8
- # the Xray bar into the app's pages. It also listens for requests to open files
9
- # with the user's editor.
7
+ # This middleware is responsible for injecting xray.js and the Xray bar into
8
+ # the app's pages. It also listens for requests to open files with the user's
9
+ # editor.
10
10
  class Middleware
11
11
  def initialize(app)
12
12
  @app = app
@@ -44,7 +44,6 @@ module Xray
44
44
  elsif Rails.application.config.assets.debug
45
45
  # Otherwise try to inject xray.js if assets are unbundled
46
46
  if append_js!(body, 'jquery', 'xray')
47
- append_js!(body, 'backbone', 'xray-backbone')
48
47
  inject_xray_bar!(body)
49
48
  end
50
49
  end
@@ -1,3 +1,3 @@
1
1
  module Xray
2
- VERSION = "0.1.23".freeze
2
+ VERSION = "0.2.0".freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xray-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.23
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brent Dillingham
@@ -24,20 +24,6 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 3.1.0
27
- - !ruby/object:Gem::Dependency
28
- name: coffee-rails
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: rspec-rails
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -80,34 +66,6 @@ dependencies:
80
66
  - - ">="
81
67
  - !ruby/object:Gem::Version
82
68
  version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: backbone-rails
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: sass-rails
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
69
  - !ruby/object:Gem::Dependency
112
70
  name: haml
113
71
  requirement: !ruby/object:Gem::Requirement
@@ -122,20 +80,6 @@ dependencies:
122
80
  - - ">="
123
81
  - !ruby/object:Gem::Version
124
82
  version: '0'
125
- - !ruby/object:Gem::Dependency
126
- name: eco
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - ">="
130
- - !ruby/object:Gem::Version
131
- version: '0'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - ">="
137
- - !ruby/object:Gem::Version
138
- version: '0'
139
83
  - !ruby/object:Gem::Dependency
140
84
  name: capybara
141
85
  requirement: !ruby/object:Gem::Requirement
@@ -151,7 +95,7 @@ dependencies:
151
95
  - !ruby/object:Gem::Version
152
96
  version: '0'
153
97
  description: Provides a dev bar and an overlay in-browser to visualize your UI's rendered
154
- partials and Backbone views
98
+ partials
155
99
  email:
156
100
  - brentdillingham@gmail.com
157
101
  executables: []
@@ -160,7 +104,7 @@ extra_rdoc_files: []
160
104
  files:
161
105
  - LICENSE
162
106
  - README.md
163
- - app/assets/javascripts/xray-backbone.js.coffee
107
+ - app/assets/javascripts/xray.js
164
108
  - app/assets/javascripts/xray.js.coffee
165
109
  - app/assets/stylesheets/xray.css
166
110
  - app/views/_xray_bar.html.erb
@@ -173,9 +117,7 @@ homepage: https://github.com/brentd/xray-rails
173
117
  licenses:
174
118
  - MIT
175
119
  metadata: {}
176
- post_install_message: |
177
- Backbone.js support will be removed from xray-rails in version 0.2.0.
178
- If you need backbone.js support, lock xray-rails to 0.1.22 to avoid breaking changes.
120
+ post_install_message:
179
121
  rdoc_options: []
180
122
  require_paths:
181
123
  - lib
@@ -1,20 +0,0 @@
1
- # Xray Backbone integration. This involves hooking into the lifecycle
2
- # of Backbone.View by monkey patching its prototype. Would love a cleaner
3
- # way of doing this, as nobody wants to this stuff in their stack traces.
4
-
5
- return unless window.Backbone && window.Xray
6
-
7
- # Wrap Backbone.View::_ensureElement to add the view to Xray once
8
- # its element has been setup.
9
- _ensureElement = Backbone.View::_ensureElement
10
- Backbone.View::_ensureElement = ->
11
- _.defer =>
12
- if info = Xray.constructorInfo @constructor
13
- Xray.ViewSpecimen.add @el, info
14
- _ensureElement.apply(this, arguments)
15
-
16
- # Cleanup when view is removed.
17
- _remove = Backbone.View::remove
18
- Backbone.View::remove = ->
19
- Xray.ViewSpecimen.remove @el
20
- _remove.apply(this, arguments)