define ["./dom", "./events", "./ajax", "./console", "./forms",  "underscore"],
  (dom, events, ajax, console, forms, _) ->Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http:#www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Provides a default handler for events related to zones. A zone is any kind of client-side element that can be updated; a zone will normally have a unique id. Typically, a client-side zone element is rendered by, and corresponds to, a server-side core/Zone component; however, certain other components (such as core/ProgressiveDisplay) may also be treated as zones.
Most often, a zone is any element with attribute data-container-type=zone and corresponds
to a core/Zone server-side component.
define ["./dom", "./events", "./ajax", "./console", "./forms",  "underscore"],
  (dom, events, ajax, console, forms, _) ->For a given element that may have the data-update-zone attribute, locates the
zone element. May return null if the zone can not be found (after logging an error
to the console).
    findZone = (element) ->
      zoneId = element.attr "data-update-zone"
      if zoneId is "^"
        zone = element.findParent "[data-container-type=zone]"
        if zone is null
          throw new Error "Unable to locate containing zone for #{element}."
        return zone
      zone = dom zoneId
      if zone is null
        throw new Error "Unable to locate zone '#{zoneId}'."
      return zone
    dom.onDocument "click", "a[data-update-zone]", (event) ->
      element = @closest "[data-update-zone]"
      unless element
        throw new Error "Could not locate containing element with data-update-zone attribute."
      zone = findZone element
      if zone
        zone.trigger events.zone.refresh,  url: element.attr "href"
      event.nativeEvent.preventDefault()
      return
    dom.onDocument "submit", "form[data-update-zone]", ->
      zone = findZone this
      if zone
        formParameters = forms.gatherParameters this
        zone.trigger events.zone.refresh,
          url: (@attr "action")
          parameters: formParameters
      return false
    dom.onDocument "submit", "form[data-async-trigger]", ->
      formParameters = forms.gatherParameters this
      @addClass "ajax-update"
      ajax (@attr "action"),
        data: formParameters
        complete: => @removeClass "ajax-update"
      return false
    dom.onDocument events.zone.update, (event) ->
      @trigger events.zone.willUpdate
      content = event.memo.contentThe server may have passed down the empty string for the content; that removes the existing content. On the other hand, the server may have not provided a content key; in that case, content is undefined which means to leave the existing content alone.
Note that currently, the willUpdate and didUpdate events are triggered even when the zone is not actually updated. That may be a bug.
      unless content is undefined
        @update content
      @trigger events.initializeComponents
      @trigger events.zone.didUpdate
    dom.onDocument events.zone.refresh, (event) ->This event may be triggered on an element inside the zone, rather than on the zone itself. Scan upwards to find the actual zone.
      zone = @closest "[data-container-type=zone]"A Zone inside a form will render some additional parameters to coordinate updates with the Form on the server.
      attr = zone.attr "data-zone-parameters"
      parameters = attr and JSON.parse attr
      simpleIdParams = if zone.attr "data-simple-ids" then {"t:suppress-namespaced-ids": true}
      ajax event.memo.url,
        data: _.extend { "t:zoneid": zone.element.id }, simpleIdParams, parameters, event.memo.parameters
        success: (response) ->
          zone.trigger events.zone.update, content: response.json?.content
    dom.onDocument "click", "a[data-async-trigger]", (event)->
      link = @closest 'a[data-async-trigger]'
      link.addClass "ajax-update"
      ajax (link.attr "href"),
        complete: -> link.removeClass "ajax-update"
      event.nativeEvent.preventDefault()
      returnLocates a zone element by its unique id attribute, and (deferred, to a later event loop cycle), performs a standard refresh of the zone. This is primarily used by the core/ProgressiveDisplay component.
    deferredZoneUpdate = (id, url) ->
      _.defer ->
        zone = dom id
        if zone is null
          console.error "Could not locate element '#{id}' to update."
          return
        zone.trigger events.zone.refresh, { url }Most of this module is document-level event handlers, but there’s also some exports:
    return { deferredZoneUpdate, findZone }