   
   # Performs a scoped querySelectAll.
   #
-  # @param [Element] scope the DOM element serving as the search scope
-  # @param [String] selector the CSS selector to query
-  # @return [NodeList, Array] the elements in the scope that match the CSS
+  # @param {HTMLElement} scope the DOM element serving as the search scope
+  # @param {String} selector the CSS selector to query
+  # @return {NodeList, Array} the elements in the scope that match the CSS
   #     selector; the scope container can belong to the returned array
   queryScope: (scope, selector) ->
     scopeMatches = false

  
  # Finds a scoping container.
  #
  # @param [String] scopeId the scope ID to look for
  # @param [Element] element the element where the lookup starts
  # @return [Element] the closest parent of the given element whose
  #     data-pwnfx-scope matches the scopeId argument; window.document is
  #     returned if no such element exists or if scope is null
  resolveScope: (scopeId, element) ->

      parent.removeChild scriptElement
      parent.insertBefore scriptElement.cloneNode(true), nextSibling
    null
  
  # Do AJAX.
  #
  # @param {String} url the request URL (e.g., "http://localhost/path/to.html")
  # @param {String} method the request method (e.g., "POST")
  # @param [HTMLFormElement] form the DOM form whose data will be submitted
  # @param [function(data)] onData callback that receives the XHR data, if the
  #                                XHR completes successfully
  xhr: (url, method, form, onData) ->
    xhr = new XMLHttpRequest
    xhr.onload = @_xhr_onload
    xhr.pwnfxOnData = onData
    xhr.open xhrMethod, xhrUrl
    xhr.send new FormData(xhrForm)    
  
  # Called when an XHR request issued by PwnFx.xhr works out.
  _xhr_onload: ->
    if @status < 200 || @status >= 300
      throw new Error("XHR result ignored due to HTTP status: #{@statusText}")
    @pwnfxOnData @responseText
  
# Singleton instance.
PwnFx = new PwnFxClass
