       parent.insertBefore scriptElement.cloneNode(true), nextSibling
     null
   
+  # Replaces an element's contents with some HTML.
+  #
+  # The JavaScript inside the HTML's <script> tags will be executed. 
+  #
+  # @param {HTMLElement} element the element whose contents will be replaced
+  # @param {String}
+  replaceHtml: (element, html) ->
+    element.innerHTML = html
+    @runScripts element
+    @wire element
+
+  # The closest form element wrapping a node.
+  #
+  # @param {HTMLElement} element the element whose parent chain will be searched
+  # @return {HTMLFormElement} the element's closest parent form, or null if the
+  #     element is not wrapped in a <form>
+  parentForm: (element) ->
+    while element
+      return element if element.nodeName == 'FORM'
+      element = element.parentNode
+    null
+  
   # Do AJAX.
   #
   # @param {String} url the request URL (e.g., "http://localhost/path/to.html")

      return true if value == refreshOldValue
      refreshOldValue = value
      
      return true if refreshPending
      refreshPending = true
      window.setTimeout ajaxRefresh, refreshInterval
      true
      
    element.addEventListener 'change', onChange, false
    element.addEventListener 'keydown', onChange, false
    element.addEventListener 'keyup', onChange, false
    
    
  # The closest form element wrapping a node.
  parentForm: (element) ->
    while element
      return element if element.nodeName == 'FORM'
      element = element.parentNode
    null

PwnFx.registerEffect 'refresh', PwnFxRefresh



    xhr = new XMLHttpRequest
    xhr.onload = @_xhr_onload
    xhr.pwnfxOnData = onData
    xhr.open method, url
    xhr.setRequestHeader 'X-Requested-With', 'XMLHttpRequest'
    if form
      xhr.send new FormData(form)
    else
      xhr.send null
  
  # Called when an XHR request issued by PwnFx.xhr works out.
  _xhr_onload: ->
