- http://rack.rubyforge.org/doc/classes/Rack/Response.html
- http://www.ruby-doc.org/stdlib-1.9.3/libdoc/open3/rdoc/Open3.html
- http://api.rubyonrails.org/classes/ActiveSupport/SafeBuffer.html
- http://apidock.com/ruby/Module/module_function
- http://markdalgleish.com/2011/03/self-executing-anonymous-functions/
- http://stackoverflow.com/questions/5764005/what-is-return-function-used-for-in-javascript
- http://stackoverflow.com/questions/3360858/why-use-in-the-name-of-javascript-variables
- http://stackoverflow.com/questions/1051782/jquery-this-vs-this
- http://api.jquery.com/is/
- http://api.jquery.com/contents/
- https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeType?redirectlocale=en-US&redirectslug=DOM%2FNode.nodeType
- http://api.jquery.com/filter/
- https://developer.mozilla.org/en-US/docs/Web/API/Node.nextSibling
- http://stackoverflow.com/questions/6459398/jquery-get-html-of-container-including-the-container-itself
- https://developer.mozilla.org/en-US/docs/Web/API/Node.parentNode
- https://developer.mozilla.org/en-US/docs/Web/API/Node.removeChild
-
overwriate ActionView::Template.render
ActionView::Template.class_eval do def render_with_xray(*args, &block) path = identifier source = render_without_xray(*args, &block) if path =~ /\.(html|slim|haml)(\.|$)/ && !path.match(/\.(js|json)\./) && !path.include?('_xray_bar') Xray.augment_template(source, path) else source end end alias_method_chain :render, :xray end
-
攔截進來的asset, app.assets.register_postprocessor
-
http://rubydoc.info/github/sstephenson/sprockets/Sprockets/Processing:register_postprocessor
app.assets.register_postprocessor 'application/javascript', :xray do |context, data|
path = context.pathname.to_s
if path =~ /^#{app.root}.+\.(js|coffee)(\.|$)/
Xray.augment_js(data, path)
else
data
end
end
-
ActiveSupport::Notifications
# This event is called near the beginning of a request cycle. We use it to # collect information about the controller and action that is responding, for # display in the Xray bar. ActiveSupport::Notifications.subscribe('start_processing.action_controller') do |*args| event = ActiveSupport::Notifications::Event.new(*args) controller_name = event.payload[:controller] action_name = event.payload[:action] path = ActiveSupport::Dependencies.search_for_file(controller_name.underscore) # Reset the request info hash for this request. # NOTE: Nothing about this is thread-safe. Could this affect anyone in dev mode? Xray.request_info.clear Xray.request_info[:controller] = { :path => path, :name => controller_name, :action => action_name } # This event is called each time during the request cycle that # ActionView renders a template. The first time it's called will most # likely be the view the controller is rendering, which is what we're # interested in. ActiveSupport::Notifications.subscribe('render_template.action_view') do |*args| event = ActiveSupport::Notifications::Event.new(*args) layout = event.payload[:layout] path = event.payload[:identifier] # We are only interested in the first notification that has a layout. if layout Xray.request_info[:view] ||= { :path => path, :layout => layout } end end
-
middleware.rb
# xray insert its js xray.js through find where's jquery and insert after it body = response.body.sub(/<body[^>]*>/) { "#{$~}\n#{xray_bar}" } # Inject js script tags if assets are unbundled if Rails.application.config.assets.debug append_js!(body, 'jquery', :xray) end # Appends the given `script_name` after the `after_script_name`. def append_js!(html, after_script_name, script_name) # Matches: # <script src="/assets/jquery.js"></script> # <script src="/assets/jquery-min.js"></script> # <script src="/assets/jquery.min.1.9.1.js"></script> html.sub!(/<script[^>]+\/#{after_script_name}([-.]{1}[\d\.]+)?([-.]{1}min)?\.js[^>]+><\/script>/) do h = ActionController::Base.helpers "#{$~}\n" + h.javascript_include_tag(script_name) end end
-
xray.js.coffee
-
http://markdalgleish.com/2011/03/self-executing-anonymous-functions/
# coffee
Xray.init = ->
# js
Xray.init = function() {};
# coffee, this will run the function by itself
Xray.init = do ->
# js
Xray.init = (function() {})();
Xray.init = do ->
console.log(this) #window
->
console.log(this) #won't run here
$ ->
console.log(this) # document
Xray.init = (function() {
console.log(this);
(function() {
return console.log(this);
});
return $(function() {
return console.log(this);
});
})();
Xray.init = do ->
#console.log(this)
$ ->
new Xray.Overlay
#console.log(this)
class Xray.Overlay
@instance: ->
@singletonInstance ||= new this
constructor: ->
console.log(this)
Xray.Overlay.singletonInstance = this # save the context when create this object
console.log(Xray.Overlay.instance()) # Overlay object
# Utility methods.
util =
# Benchmark a piece of code
bm: (name, fn) ->
time = new Date
result = fn()
console.log "#{name} : #{new Date() - time}ms"
result
$('<div id="xray-overlay">')
=> [<div id="xray-overlay"></div>]
# Find all <!-- XRAY START ... --> comments
comments = $('*:not(iframe,script)').contents().filter ->
this.nodeType == 8 and this.data[0..9] == "XRAY START"
# Find the <!-- XRAY END ... --> comment for each. Everything between the
# start and end comment becomes the contents of an Xray.TemplateSpecimen.
for comment in comments
[_, id, path] = comment.data.match(/^XRAY START (\d+) (.*)$/)
$templateContents = new jQuery
class Xray.Specimen
@add: (el, info = {}) ->
@all.push new this(el, info) # It could push the instance(it extend, TemplateSpecimen or ViewSpecimen) to all array
# Wraps elements that were rendered by a template, e.g. a Rails partial or
# a client-side rendered JS template.
class Xray.TemplateSpecimen extends Xray.Specimen
@all = []
# Wraps elements that constitute a Javascript "view" object, e.g.
# Backbone.View.
class Xray.ViewSpecimen extends Xray.Specimen
@all = []
# Add the template specimen
Xray.TemplateSpecimen.add $templateContents,
name: path.split('/').slice(-1)[0]
path: path
# Wraps elements that constitute a Javascript "view" object, e.g.
# Backbone.View.
class Xray.ViewSpecimen extends Xray.Specimen
@all = []