brentd / xray-rails

☠️ A development tool that reveals your UI's bones

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Need ability to disable Xray entirely for a given controller action

jpegjames opened this issue · comments

Maybe, I'm missing something, but I have view that I need to disable xray on. In the controller, I've passed render xray: false, and it does prevent it from rendering.

I've tried a bunch of combinations. This particular controller action has no other functionality. Here's everything that I've tried:

def show
  render xray: false 
end
def show
  render 'show', xray: false 
end
def show
  respond_to do |format|
    format.html{ render 'show', xray: false }
  end
end

Any thoughts? Is this only not working for me? I've tried it on several different actions and controllers, but it initiates every time.


I'm running Rails 3.2.21 and I just updated to xray-rails 0.1.21. I am also using Turbolinks, but have tried by refreshing the page each time and it still stays enabled.

Hi, thanks for the report!

To be honest, I've never used the xray: false feature and this is the first time I've been made aware of it (I currently maintain the gem but am not the original author).

It is quite possible that this feature is broken, either in general or for Rails 3.2 specifically. I would appreciate any additional investigation you could provide on this.

Just to be clear: my expectation of this feature based on the README is that passing xray: false should still render the view. The only difference should be that the special xray HTML comments will be omitted. Thus when you activate xray with the keyboard shortcut, that particular view will not be highlighted.

Intuitively this makes sense for a partial render, but it is not entirely clear to me what is supposed to happen if you pass xray: false for the entire view rendered by the controller. Should it completely disable xray?

What is your expectation?

@mattbrictson: Thanks for your response.

I was expecting to pass xray: false to not send down the xray related code in the the HTML views (in other words, command+shift+x should do nothing) but yes, the view should still work as normal. We have one JavaScript plugin that fails to work with xray (so when working in dev on that section, we have to remove x-ray from the Gemfile and restart the server).

Reading through the code, I found this line in engine.rb that seems to handle this option, but I don't see anywhere where render_with_xray is called.

I also found this test.

I'm not too familiar with the inner-workings of xray, so where is the x-ray html interjected into the view? Is it the render_with_xray method or something else?

(Tagging one of my other developers on this: @lebrauncom)

So, my understanding is that xray-rails does two different things wrt HTML injection:

  1. For every HTTP response, it adds some global markup (e.g. the xray toolbar) and a <script> element to load the necessary xray JavaScript. This happens regardless of whether or not you specify xray: false. The code for it is in middleware.rb.
  2. For each view template rendered as part of the response, xray surrounds the rendered view with special HTML comments. These comments tell the xray JavaScript where partials begin and end in the DOM so that it can draw bounding boxes and link to the source files when you press command+shift+x. These injected HTML comments are what you can disable with xray: false (at least, this is my assumption).

Does this help shed some light on what is happening?

To my knowledge there is no way to entirely disable the xray middleware for a given text/html response, so there will always be some xray markup and JavaScript injected.

For every HTTP response, it adds some global markup (e.g. the xray toolbar) and a <script> element to load the necessary xray JavaScript. This happens regardless of whether or not you specify xray: false. The code for it is in middleware.rb.

Yes, this is happening whether or not xray: false is passed.

For each view template rendered as part of the response, xray surrounds the rendered view with special HTML comments. These comments tell the xray JavaScript where partials begin and end in the DOM so that it can draw bounding boxes and link to the source files when you press command+shift+x. These injected HTML comments are what you can disable with xray: false (at least, this is my assumption).

What you describe, might be OK but the xray comments are still being passed into the HTML when xray: false. I've rendered the same page xray: false and xray: true and both times the same number of xray comments were in the raw HTML code command+shift+x responded the same way in both browser windows.

@mattbrictson: Follow up question: Where does X-Ray inject the HTML comments? The middleware.rb reference above seems to just be for the x-ray bar and assets.

Comments are injected using Xray.augment_template, which is defined here:

def self.augment_template(source, path)
id = next_id
if source.include?('<!DOCTYPE')
return source
end
# skim doesn't allow html comments, so use skim's comment syntax if it's skim
if path =~ /\.(skim|hamlc)(\.|$)/
augmented = "/!XRAY START #{id} #{path}\n#{source}\n/!XRAY END #{id}"
else
augmented = "<!--XRAY START #{id} #{path}-->\n#{source}\n<!--XRAY END #{id}-->"
end
ActiveSupport::SafeBuffer === source ? ActiveSupport::SafeBuffer.new(augmented) : augmented
end

This happens whenever a view template is rendered, which is accomplished by a monkey patch registered by engine.rb, here:

# Monkey patch ActionView::Template to augment server-side templates
# with filepath information. See `Xray.augment_template` for details.
ActionView::Template.class_eval do
def render_with_xray(*args, &block)
path = identifier
view = args.first
source = render_without_xray(*args, &block)
suitable_template = !(view.respond_to?(:mailer) && view.mailer) &&
!path.include?('_xray_bar') &&
path =~ /\.(html|slim|haml|hamlc)(\.|$)/ &&
path !~ /\.(js|json|css)(\.|$)/
options = args.last.kind_of?(Hash) ? args.last : {}
if suitable_template && !(options.has_key?(:xray) && (options[:xray] == false))
Xray.augment_template(source, path)
else
source
end
end
alias_method_chain :render, :xray
end

Was there any resolution to this problem? I'm encountering it right now

@jpegjames @pcragone the solution is to use the locals parameter, like this:

render locals: {xray: false} 

As far as I can tell, you use xray: false when rendering a partial:

render partial: 'foo', xray: false

and use the locals parameter otherwhise.

To reiterate: the xray: false option is for disabling Xray for a specific partial template. There is no way to disable Xray for an entire response. I will update the README to clarify this.

I'm re-classifying this issue as a feature request: namely, the ability to disable Xray entirely for a given controller action.

@mattbrictson: Thanks for updating the README. I think that caused some confusion as it seemed like it could be disabled completely for a given page/request.

I would personally love to see that feature, but we make heavy use of partials so this may still be a suitable workaround.

I would love to see this available. We have modal JS library that expects one root element that is broken by x-ray instrumentation.