window.Xray = {} return unless $ = window.jQuery # Max CSS z-index. The overlay and xray bar use this. MAX_ZINDEX = 2147483647 # Initialize Xray. Called immediately, but some setup is deferred until DOM ready. Xray.init = do -> return if Xray.initialized Xray.initialized = true is_mac = navigator.platform.toUpperCase().indexOf('MAC') isnt -1 # Register keyboard shortcuts $(document).keydown (e) -> # cmd+shift+x on Mac, ctrl+shift+x on other platforms if (is_mac and e.metaKey or !is_mac and e.ctrlKey) and e.shiftKey and e.keyCode is 88 if Xray.isShowing then Xray.hide() else Xray.show() if Xray.isShowing and e.keyCode is 27 # esc Xray.hide() $ -> # Instantiate the overlay singleton. new Xray.Overlay # Go ahead and do a pass on the DOM to find templates. Xray.findTemplates() # Ready to rock. console?.log "Ready to Xray. Press #{if is_mac then 'cmd+shift+x' else 'ctrl+shift+x'} to scan your UI." # Returns all currently created Xray.Specimen objects. Xray.specimens = -> Xray.ViewSpecimen.all.concat Xray.TemplateSpecimen.all # Looks up the stored constructor info Xray.constructorInfo = (constructor) -> if window.XrayPaths for own info, func of window.XrayPaths return JSON.parse(info) if func == constructor null # Scans the document for templates, creating Xray.TemplateSpecimens for them. Xray.findTemplates = -> util.bm 'findTemplates', -> # Find all comments comments = $('*:not(iframe,script)').contents().filter -> this.nodeType == 8 and this.data[0..9] == "XRAY START" # Find the 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 el = comment.nextSibling until !el or (el.nodeType == 8 and el.data == "XRAY END #{id}") if el.nodeType == 1 and el.tagName != 'SCRIPT' $templateContents.push el el = el.nextSibling # Remove XRAY template comments from the DOM. el.parentNode.removeChild(el) if el?.nodeType == 8 comment.parentNode.removeChild(comment) # Add the template specimen Xray.TemplateSpecimen.add $templateContents, name: path.split('/').slice(-1)[0] path: path # Open the given filesystem path by calling out to Xray's server. Xray.open = (path) -> $.ajax(url: "/_xray/open?path=#{path}") # Show the Xray overlay Xray.show = (type = null) -> Xray.Overlay.instance().show(type) # Hide the Xray overlay Xray.hide = -> Xray.Overlay.instance().hide() Xray.toggleSettings = -> Xray.Overlay.instance().settings.toggle() # Wraps a DOM element that Xray is tracking. This is subclassed by # Xray.TemplateSpecimen and Xray.ViewSpecimen. class Xray.Specimen @add: (el, info = {}) -> @all.push new this(el, info) @remove: (el) -> @find(el)?.remove() @find: (el) -> el = el[0] if el instanceof jQuery for specimen in @all return specimen if specimen.el == el null @reset: -> @all = [] constructor: (contents, info = {}) -> @el = if contents instanceof jQuery then contents[0] else contents @$contents = $(contents) @name = info.name @path = info.path remove: -> idx = @constructor.all.indexOf(this) @constructor.all.splice(idx, 1) unless idx == -1 isVisible: -> @$contents.length and @$contents.is(':visible') makeBox: -> @bounds = util.computeBoundingBox(@$contents) @$box = $("