lib/assets/javascripts/unpoly/flow.js.coffee in unpoly-rails-0.27.1 vs lib/assets/javascripts/unpoly/flow.js.coffee in unpoly-rails-0.27.2
- old
+ new
@@ -181,20 +181,29 @@
of all the viewports around or below the updated element. The position
will be reset to the last known top position before a previous
history change for the current URL.
@param {Boolean} [options.cache]
Whether to use a [cached response](/up.proxy) if available.
- @param {Element|jQuery} [options.origin]
- The element that triggered the replacement. The element's selector will
- be substituted for the `&` shorthand in the target selector.
@param {String} [options.historyMethod='push']
@param {Object} [options.headers={}]
An object of additional header key/value pairs to send along
with the request.
@param {Boolean} [options.requireMatch=true]
Whether to raise an error if the given selector is missing in
either the current page or in the response.
+ @param {Element|jQuery} [options.origin]
+ The element that triggered the replacement.
+
+ The element's selector will be substituted for the `&` shorthand in the target selector.
+ @param {String} [options.layer='auto']
+ The name of the layer that ought to be updated. Valid values are
+ `auto`, `page`, `modal` and `popup`.
+
+ If set to `auto` (default), Unpoly will try to find a match in the
+ same layer as the element that triggered the replacement (see `options.origin`).
+ If that element is not known, or no match was found in that layer,
+ Unpoly will search in other layers, starting from the topmost layer.
@return {Promise}
A promise that will be resolved when the page has been updated.
@stable
###
replace = (selectorOrElement, url, options) ->
@@ -319,13 +328,14 @@
@experimental
###
extract = (selectorOrElement, html, options) ->
up.log.group 'Extracting %s from %d bytes of HTML', selectorOrElement, html?.length, ->
options = u.options(options,
- historyMethod: 'push',
- requireMatch: true,
+ historyMethod: 'push'
+ requireMatch: true
keep: true
+ layer: 'auto'
)
selector = resolveSelector(selectorOrElement, options.origin)
response = parseResponse(html, options)
options.title ||= response.title()
@@ -349,19 +359,17 @@
return $.when(swapPromises...)
promise = promise.then(options.afterSwap) if options.afterSwap
promise
findOldFragment = (selector, options) ->
- # Prefer to replace fragments in an open popup or modal
- first(".up-popup #{selector}") ||
- first(".up-modal #{selector}") ||
- first(selector) ||
- oldFragmentNotFound(selector, options)
+ first(selector, options) || oldFragmentNotFound(selector, options)
oldFragmentNotFound = (selector, options) ->
if options.requireMatch
- message = 'Could not find selector %s in current body HTML'
+ layerProse = options.layer
+ layerProse = 'page, modal or popup' if layerProse == 'auto'
+ message = "Could not find selector %s in the current #{layerProse}"
if message[0] == '#'
message += ' (avoid using IDs)'
u.error(message, selector)
filterScripts = ($element, options) ->
@@ -704,27 +712,58 @@
Returns `undefined` if no element matches these conditions.
@function up.first
@param {String|Element|jQuery|Array<Element>} selectorOrElement
- @return {jQuery}
+ @param {String} options.layer
+ The name of the layer in which to find the element. Valid values are
+ `auto`, `page`, `modal` and `popup`.
+ @param {}
+ @return {jQuery|Undefined}
The first element that is neither a ghost or being destroyed,
or `undefined` if no such element was given.
@experimental
###
- first = (selectorOrElement) ->
- elements = undefined
- if u.isString(selectorOrElement)
- elements = $(selectorOrElement).get()
+ first = (selectorOrElement, options) ->
+ options = u.options(options, layer: 'auto')
+ if options.layer == 'auto'
+ firstInPriority(selectorOrElement, options.origin)
else
- elements = selectorOrElement
+ firstInLayer(selectorOrElement, options.layer)
+
+ firstInPriority = (selectorOrElement, origin) ->
+ layers = ['popup', 'modal', 'page']
$match = undefined
- for element in elements
+ if u.isPresent(origin)
+ originLayer = layerOf(origin)
+ u.remove(layers, originLayer)
+ layers.unshift(originLayer)
+ for layer in layers
+ if $match = firstInLayer(selectorOrElement, layer)
+ break
+ $match
+
+ firstInLayer = (selectorOrElement, layer) ->
+ $elements = $(selectorOrElement)
+ $match = undefined
+ for element in $elements
$element = $(element)
- if isRealElement($element)
+ if isRealElement($element) && matchesLayer($element, layer)
$match = $element
break
$match
+
+ layerOf = (selectorOrElement) ->
+ $element = $(selectorOrElement)
+ if up.popup.contains($element)
+ 'popup'
+ else if up.modal.contains($element)
+ 'modal'
+ else
+ 'page'
+
+ matchesLayer = (selectorOrElement, layer) ->
+ layerOf(selectorOrElement) == layer
###*
Destroys the given element or selector.
Takes care that all [`up.compiler`](/up.compiler) destructors, if any, are called.