unpoly-rails 0.28.1 → 0.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of unpoly-rails might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +19 -1
- data/dist/unpoly.js +376 -259
- data/dist/unpoly.min.js +3 -3
- data/lib/assets/javascripts/unpoly/browser.js.coffee +2 -2
- data/lib/assets/javascripts/unpoly/bus.js.coffee +40 -13
- data/lib/assets/javascripts/unpoly/flow.js.coffee +9 -9
- data/lib/assets/javascripts/unpoly/form.js.coffee +18 -18
- data/lib/assets/javascripts/unpoly/history.js.coffee +1 -1
- data/lib/assets/javascripts/unpoly/layout.js.coffee +9 -9
- data/lib/assets/javascripts/unpoly/link.js.coffee +34 -24
- data/lib/assets/javascripts/unpoly/modal.js.coffee +38 -37
- data/lib/assets/javascripts/unpoly/motion.js.coffee +20 -23
- data/lib/assets/javascripts/unpoly/navigation.js.coffee +101 -37
- data/lib/assets/javascripts/unpoly/popup.js.coffee +24 -16
- data/lib/assets/javascripts/unpoly/proxy.js.coffee +3 -3
- data/lib/assets/javascripts/unpoly/syntax.js.coffee +29 -37
- data/lib/assets/javascripts/unpoly/tooltip.js.coffee +18 -9
- data/lib/assets/javascripts/unpoly/util.js.coffee +15 -7
- data/lib/unpoly/rails/version.rb +1 -1
- data/spec_app/Gemfile.lock +1 -1
- data/spec_app/spec/javascripts/helpers/trigger.js.coffee +6 -0
- data/spec_app/spec/javascripts/up/bus_spec.js.coffee +9 -8
- data/spec_app/spec/javascripts/up/form_spec.js.coffee +10 -10
- data/spec_app/spec/javascripts/up/link_spec.js.coffee +25 -20
- data/spec_app/spec/javascripts/up/modal_spec.js.coffee +53 -44
- data/spec_app/spec/javascripts/up/navigation_spec.js.coffee +8 -8
- data/spec_app/spec/javascripts/up/popup_spec.js.coffee +92 -44
- data/spec_app/spec/javascripts/up/tooltip_spec.js.coffee +46 -4
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5c3dd39115176a2678dd711465e699abf2a6075e
|
4
|
+
data.tar.gz: 3aa54c6a3322d1744049d08e28d8951a0202937a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c35a16fbcff7161a323a017fcc4fcaa05987d70e4fd0af46de864b4b19b6d626478c69aa72deaf3fdb032b8db516e31ee7545178e8f381e4ae676224fd06f7ca
|
7
|
+
data.tar.gz: f2bb1070125d3cb2a774d19efccd6e3d03b6ff20d6aa70d5683907a041e108a760a2067a55c7d7a0e9a3425ef5767306656b21e4e8e56927d2cc27416653a8ee
|
data/CHANGELOG.md
CHANGED
@@ -10,8 +10,26 @@ Unreleased
|
|
10
10
|
|
11
11
|
### Compatible changes
|
12
12
|
|
13
|
+
|
14
|
+
### Breaking changes
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
0.29.0
|
19
|
+
------
|
20
|
+
|
21
|
+
### Compatible changes
|
22
|
+
|
23
|
+
- [`up.popup.attach`](/up.popup.attach) now has a `{ html }` option. This allows you to extract popup contents
|
24
|
+
from a HTML string without making a network request.
|
25
|
+
- [`up.tooltip.attach`](/up.tooltip.attach) now has a `{ text }` option which automatically escapes the given string.
|
26
|
+
- Fix a bug on Firefox where the page width would jump by the scrollbar width when opening a modal.
|
27
|
+
- Fix a bug where modals would close when following a link to a cached destination.
|
28
|
+
|
13
29
|
### Breaking changes
|
14
30
|
|
31
|
+
- Events handled by Unpoly selectors will now longer bubble up the DOM.
|
32
|
+
|
15
33
|
|
16
34
|
0.28.1
|
17
35
|
------
|
@@ -414,7 +432,7 @@ Unreleased
|
|
414
432
|
request and response.
|
415
433
|
- [`up.follow`](/up.follow) and [`up.replace`](/up.replace) now have an option `{ failTarget }`.
|
416
434
|
Use it to define the selector to replace if the server responds with a non-200 status code.
|
417
|
-
- [`[up-target]`](/up-target) and [`up-follow`](/up
|
435
|
+
- [`[up-target]`](/a-up-target) and [`up-follow`](/a-up-follow) now have a modifying attribute `up-fail-target`.
|
418
436
|
Use it to define the selector to replace if the server responds with a non-200 status code.
|
419
437
|
- New utility method [`up.util.reject`](/up.util.reject)
|
420
438
|
- New utility method [`up.util.only`](/up.util.only)
|
data/dist/unpoly.js
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
(function() {
|
7
7
|
window.up = {
|
8
|
-
version: "0.
|
8
|
+
version: "0.29.0"
|
9
9
|
};
|
10
10
|
|
11
11
|
}).call(this);
|
@@ -32,7 +32,7 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
32
32
|
@function up.util.noop
|
33
33
|
@experimental
|
34
34
|
*/
|
35
|
-
var $createElementFromSelector, $createPlaceholder, ANIMATION_DEFERRED_KEY, DivertibleChain, ESCAPE_HTML_ENTITY_MAP, all, any, appendRequestData, cache, castedAttr, clientSize, compact, config, contains, copy, copyAttributes, createElement, createElementFromHtml, cssAnimate, detect, documentHasVerticalScrollbar, each, escapeHtml, escapePressed, except, extend, extractOptions, fail, findWithSelf, finishCssAnimate, fixedToAbsolute, forceCompositing, forceRepaint, identity, intersect, isArray, isBlank, isDeferred, isDefined, isDetached, isElement, isFixed, isFormData, isFunction, isGiven, isHash, isJQuery, isMissing, isNull, isNumber, isObject, isPresent, isPromise, isStandardPort, isString, isUndefined, isUnmodifiedKeyEvent, isUnmodifiedMouseEvent, last, locationFromXhr, map, measure, memoize, merge, methodFromXhr, multiSelector, nextFrame, nonUpClasses, noop, normalizeMethod, normalizeUrl, nullJQuery, offsetParent, once, only, opacity, option, options, parseUrl, pluckData, pluckKey, presence, presentAttr, previewable, reject, remove, requestDataAsArray, requestDataAsQuery, requestDataFromForm, resolvableWhen, resolvedDeferred, resolvedPromise, scrollbarWidth, select, selectorForElement, setMissingAttrs, setTimer, submittedValue, temporaryCss, times, titleFromXhr, toArray, trim, unJQuery, uniq, unresolvableDeferred, unresolvablePromise, unwrapElement, whenReady;
|
35
|
+
var $createElementFromSelector, $createPlaceholder, ANIMATION_DEFERRED_KEY, DivertibleChain, ESCAPE_HTML_ENTITY_MAP, all, any, appendRequestData, cache, castedAttr, clientSize, compact, config, contains, copy, copyAttributes, createElement, createElementFromHtml, cssAnimate, detect, documentHasVerticalScrollbar, each, escapeHtml, escapePressed, except, extend, extractOptions, fail, findWithSelf, finishCssAnimate, fixedToAbsolute, forceCompositing, forceRepaint, identity, intersect, isArray, isBlank, isDeferred, isDefined, isDetached, isElement, isFixed, isFormData, isFunction, isGiven, isHash, isJQuery, isMissing, isNull, isNumber, isObject, isPresent, isPromise, isStandardPort, isString, isUndefined, isUnmodifiedKeyEvent, isUnmodifiedMouseEvent, last, locationFromXhr, map, measure, memoize, merge, methodFromXhr, multiSelector, nextFrame, nonUpClasses, noop, normalizeMethod, normalizeUrl, nullJQuery, offsetParent, once, only, opacity, option, options, parseUrl, pluckData, pluckKey, presence, presentAttr, previewable, reject, remove, requestDataAsArray, requestDataAsQuery, requestDataFromForm, resolvableWhen, resolvedDeferred, resolvedPromise, scrollbarWidth, select, selectorForElement, sequence, setMissingAttrs, setTimer, submittedValue, temporaryCss, times, titleFromXhr, toArray, trim, unJQuery, uniq, unresolvableDeferred, unresolvablePromise, unwrapElement, whenReady;
|
36
36
|
noop = $.noop;
|
37
37
|
|
38
38
|
/**
|
@@ -983,8 +983,8 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
983
983
|
position: 'absolute',
|
984
984
|
top: '0',
|
985
985
|
left: '0',
|
986
|
-
width: '
|
987
|
-
height: '
|
986
|
+
width: '100px',
|
987
|
+
height: '100px',
|
988
988
|
overflowY: 'scroll'
|
989
989
|
});
|
990
990
|
$outer.appendTo(document.body);
|
@@ -1949,19 +1949,26 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
1949
1949
|
};
|
1950
1950
|
|
1951
1951
|
/**
|
1952
|
-
Throws
|
1952
|
+
Throws a [Javascript error](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error)
|
1953
1953
|
with the given message.
|
1954
1954
|
|
1955
|
-
The message will also be printed to the [error log](/up.log.error).
|
1955
|
+
The message will also be printed to the [error log](/up.log.error). Also a notification will be shown at the bottom of the screen.
|
1956
1956
|
|
1957
|
-
|
1957
|
+
The message may contain [substitution marks](https://developer.mozilla.org/en-US/docs/Web/API/console#Using_string_substitutions).
|
1958
1958
|
|
1959
|
-
|
1959
|
+
\#\#\# Examples
|
1960
1960
|
|
1961
1961
|
up.fail('Division by zero')
|
1962
1962
|
up.fail('Unexpected result %o', result)
|
1963
1963
|
|
1964
1964
|
@function up.fail
|
1965
|
+
@param {String} message
|
1966
|
+
A message with details about the error.
|
1967
|
+
|
1968
|
+
The message can contain [substitution marks](https://developer.mozilla.org/en-US/docs/Web/API/console#Using_string_substitutions)
|
1969
|
+
like `%s` or `%o`.
|
1970
|
+
@param {Array<String>} vars...
|
1971
|
+
A list of variables to replace any substitution marks in the error message.
|
1965
1972
|
@experimental
|
1966
1973
|
*/
|
1967
1974
|
fail = function() {
|
@@ -2163,21 +2170,21 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
2163
2170
|
return $field.val();
|
2164
2171
|
}
|
2165
2172
|
};
|
2166
|
-
return {
|
2167
2173
|
|
2168
|
-
|
2169
|
-
|
2170
|
-
|
2171
|
-
|
2172
|
-
|
2173
|
-
|
2174
|
-
|
2175
|
-
|
2176
|
-
|
2177
|
-
|
2178
|
-
|
2179
|
-
|
2180
|
-
|
2174
|
+
/**
|
2175
|
+
@function up.util.sequence
|
2176
|
+
@internal
|
2177
|
+
*/
|
2178
|
+
sequence = function() {
|
2179
|
+
var functions;
|
2180
|
+
functions = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|
2181
|
+
return function() {
|
2182
|
+
return map(functions, function(f) {
|
2183
|
+
return f();
|
2184
|
+
});
|
2185
|
+
};
|
2186
|
+
};
|
2187
|
+
return {
|
2181
2188
|
isDetached: isDetached,
|
2182
2189
|
requestDataAsArray: requestDataAsArray,
|
2183
2190
|
requestDataAsQuery: requestDataAsQuery,
|
@@ -2282,7 +2289,8 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
2282
2289
|
identity: identity,
|
2283
2290
|
escapeHtml: escapeHtml,
|
2284
2291
|
DivertibleChain: DivertibleChain,
|
2285
|
-
submittedValue: submittedValue
|
2292
|
+
submittedValue: submittedValue,
|
2293
|
+
sequence: sequence
|
2286
2294
|
};
|
2287
2295
|
})($);
|
2288
2296
|
|
@@ -2372,7 +2380,7 @@ we can't currently get rid off.
|
|
2372
2380
|
It also prints substitution strings (e.g. `console.log("From %o to %o", "a", "b")`)
|
2373
2381
|
as a single string if the browser console does not support substitution strings.
|
2374
2382
|
|
2375
|
-
|
2383
|
+
\#\#\# Example
|
2376
2384
|
|
2377
2385
|
up.browser.puts('log', 'Hi world');
|
2378
2386
|
up.browser.puts('error', 'There was an error in %o', obj);
|
@@ -2534,7 +2542,7 @@ we can't currently get rid off.
|
|
2534
2542
|
[string substitution](https://developer.mozilla.org/en-US/docs/Web/API/console#Using_string_substitutions)
|
2535
2543
|
in `console` functions.
|
2536
2544
|
|
2537
|
-
|
2545
|
+
\#\#\# Example for string substition
|
2538
2546
|
|
2539
2547
|
console.log("Hello %o!", "Judy");
|
2540
2548
|
|
@@ -2705,7 +2713,7 @@ This improves jQuery's [`on`](http://api.jquery.com/on/) in multiple ways:
|
|
2705
2713
|
var slice = [].slice;
|
2706
2714
|
|
2707
2715
|
up.bus = (function($) {
|
2708
|
-
var boot, emit, emitReset, forgetUpDescription, live, liveUpDescriptions, logEmission, nextUpDescriptionNumber, nobodyPrevents, onEscape, rememberUpDescription, restoreSnapshot, snapshot, u, unbind, upDescriptionNumber, upDescriptionToJqueryDescription, upListenerToJqueryListener, whenEmitted;
|
2716
|
+
var boot, consumeAction, emit, emitReset, forgetUpDescription, haltEvent, live, liveUpDescriptions, logEmission, nextUpDescriptionNumber, nobodyPrevents, onEscape, rememberUpDescription, restoreSnapshot, snapshot, u, unbind, upDescriptionNumber, upDescriptionToJqueryDescription, upListenerToJqueryListener, whenEmitted;
|
2709
2717
|
u = up.util;
|
2710
2718
|
liveUpDescriptions = {};
|
2711
2719
|
nextUpDescriptionNumber = 0;
|
@@ -2768,7 +2776,7 @@ This improves jQuery's [`on`](http://api.jquery.com/on/) in multiple ways:
|
|
2768
2776
|
Other than jQuery, Unpoly will silently discard event listeners
|
2769
2777
|
on [unsupported browsers](/up.browser.isSupported).
|
2770
2778
|
|
2771
|
-
|
2779
|
+
\#\#\# Attaching structured data
|
2772
2780
|
|
2773
2781
|
In case you want to attach structured data to the event you're observing,
|
2774
2782
|
you can serialize the data to JSON and put it into an `[up-data]` attribute:
|
@@ -2782,7 +2790,7 @@ This improves jQuery's [`on`](http://api.jquery.com/on/) in multiple ways:
|
|
2782
2790
|
console.log("This is %o who is %o years old", data.name, data.age);
|
2783
2791
|
});
|
2784
2792
|
|
2785
|
-
|
2793
|
+
\#\#\# Unbinding an event listener
|
2786
2794
|
|
2787
2795
|
`up.on` returns a function that unbinds the event listeners when called:
|
2788
2796
|
|
@@ -2806,7 +2814,7 @@ This improves jQuery's [`on`](http://api.jquery.com/on/) in multiple ways:
|
|
2806
2814
|
// Unbind the listener
|
2807
2815
|
up.off('click', listener)
|
2808
2816
|
|
2809
|
-
|
2817
|
+
\#\#\# Migrating jQuery event handlers to `up.on`
|
2810
2818
|
|
2811
2819
|
Within the event handler, Unpoly will bind `this` to the
|
2812
2820
|
native DOM element to help you migrate your existing jQuery code to
|
@@ -2857,7 +2865,7 @@ This improves jQuery's [`on`](http://api.jquery.com/on/) in multiple ways:
|
|
2857
2865
|
/**
|
2858
2866
|
Unbinds an event listener previously bound with [`up.on`](/up.on).
|
2859
2867
|
|
2860
|
-
|
2868
|
+
\#\#\# Example
|
2861
2869
|
|
2862
2870
|
Let's say you are listing to clicks on `.button` elements:
|
2863
2871
|
|
@@ -2903,7 +2911,7 @@ This improves jQuery's [`on`](http://api.jquery.com/on/) in multiple ways:
|
|
2903
2911
|
Other code can subscribe to events with that name using
|
2904
2912
|
[`up.on`](/up.on) or by [binding a jQuery event listener](http://api.jquery.com/on/) to `document`.
|
2905
2913
|
|
2906
|
-
|
2914
|
+
\#\#\# Example
|
2907
2915
|
|
2908
2916
|
up.on('my:event', function(event) {
|
2909
2917
|
console.log(event.foo);
|
@@ -2948,16 +2956,18 @@ This improves jQuery's [`on`](http://api.jquery.com/on/) in multiple ways:
|
|
2948
2956
|
if (eventProps.hasOwnProperty('message')) {
|
2949
2957
|
niceMessage = eventProps.message;
|
2950
2958
|
delete eventProps.message;
|
2951
|
-
if (
|
2952
|
-
|
2953
|
-
|
2954
|
-
niceMessageArgs = [];
|
2955
|
-
}
|
2956
|
-
if (niceMessage) {
|
2957
|
-
if (u.isPresent(eventProps)) {
|
2958
|
-
return up.puts.apply(up, [niceMessage + " (%s (%o))"].concat(slice.call(niceMessageArgs), [eventName], [eventProps]));
|
2959
|
+
if (niceMessage !== false) {
|
2960
|
+
if (u.isArray(niceMessage)) {
|
2961
|
+
ref = niceMessage, niceMessage = ref[0], niceMessageArgs = 2 <= ref.length ? slice.call(ref, 1) : [];
|
2959
2962
|
} else {
|
2960
|
-
|
2963
|
+
niceMessageArgs = [];
|
2964
|
+
}
|
2965
|
+
if (niceMessage) {
|
2966
|
+
if (u.isPresent(eventProps)) {
|
2967
|
+
return up.puts.apply(up, [niceMessage + " (%s (%o))"].concat(slice.call(niceMessageArgs), [eventName], [eventProps]));
|
2968
|
+
} else {
|
2969
|
+
return up.puts.apply(up, [niceMessage + " (%s)"].concat(slice.call(niceMessageArgs), [eventName]));
|
2970
|
+
}
|
2961
2971
|
}
|
2962
2972
|
}
|
2963
2973
|
} else {
|
@@ -3036,6 +3046,32 @@ This improves jQuery's [`on`](http://api.jquery.com/on/) in multiple ways:
|
|
3036
3046
|
});
|
3037
3047
|
};
|
3038
3048
|
|
3049
|
+
/**
|
3050
|
+
Stops the given event from propagating and prevents the default action.
|
3051
|
+
|
3052
|
+
@function up.bus.haltEvent
|
3053
|
+
@internal
|
3054
|
+
*/
|
3055
|
+
haltEvent = function(event) {
|
3056
|
+
event.stopImmediatePropagation();
|
3057
|
+
event.stopPropagation();
|
3058
|
+
return event.preventDefault();
|
3059
|
+
};
|
3060
|
+
|
3061
|
+
/**
|
3062
|
+
@function up.bus.consumeAction
|
3063
|
+
@internal
|
3064
|
+
*/
|
3065
|
+
consumeAction = function(event) {
|
3066
|
+
haltEvent(event);
|
3067
|
+
if (event.type !== 'up:action:consumed') {
|
3068
|
+
return emit('up:action:consumed', {
|
3069
|
+
$element: $(event.target),
|
3070
|
+
message: false
|
3071
|
+
});
|
3072
|
+
}
|
3073
|
+
};
|
3074
|
+
|
3039
3075
|
/**
|
3040
3076
|
Makes a snapshot of the currently registered event listeners,
|
3041
3077
|
to later be restored through [`up.bus.reset`](/up.bus.reset).
|
@@ -3149,6 +3185,8 @@ This improves jQuery's [`on`](http://api.jquery.com/on/) in multiple ways:
|
|
3149
3185
|
whenEmitted: whenEmitted,
|
3150
3186
|
onEscape: onEscape,
|
3151
3187
|
emitReset: emitReset,
|
3188
|
+
haltEvent: haltEvent,
|
3189
|
+
consumeAction: consumeAction,
|
3152
3190
|
boot: boot
|
3153
3191
|
};
|
3154
3192
|
})(jQuery);
|
@@ -3436,36 +3474,23 @@ Toast alerts
|
|
3436
3474
|
}).call(this);
|
3437
3475
|
|
3438
3476
|
/**
|
3439
|
-
|
3440
|
-
|
3441
|
-
|
3442
|
-
Unpoly keeps a persistent Javascript environment during page transitions.
|
3443
|
-
If you wire Javascript to run on `ready` or `onload` events, those scripts will
|
3444
|
-
only run during the initial page load. Subsequently [inserted](/up.replace)
|
3445
|
-
page fragments will not be compiled.
|
3446
|
-
|
3447
|
-
Let's say your Javascript plugin wants you to call `lightboxify()`
|
3448
|
-
on links that should open a lightbox. You decide to
|
3449
|
-
do this for all links with an `lightbox` class:
|
3450
|
-
|
3451
|
-
<a href="river.png" class="lightbox">River</a>
|
3452
|
-
<a href="ocean.png" class="lightbox">Ocean</a>
|
3477
|
+
Custom Javascript
|
3478
|
+
=================
|
3453
3479
|
|
3454
|
-
|
3480
|
+
Every app needs a way to pair Javascript snippets with certain HTML elements,
|
3481
|
+
in order to integrate libraries or implement custom behavior.
|
3455
3482
|
|
3456
|
-
|
3457
|
-
$('a.lightbox').lightboxify();
|
3458
|
-
});
|
3483
|
+
Unpoly lets you organize your Javascript snippets using [compilers](/up.compiler).
|
3459
3484
|
|
3460
|
-
|
3485
|
+
For instance, to activate the [Masonry](http://masonry.desandro.com/) jQuery plugin for every element
|
3486
|
+
with a `grid` class, use this compiler:
|
3461
3487
|
|
3462
|
-
up.compiler('
|
3463
|
-
$element.
|
3488
|
+
up.compiler('.grid', function($element) {
|
3489
|
+
$element.masonry();
|
3464
3490
|
});
|
3465
3491
|
|
3466
|
-
The compiler function will be called on matching elements when
|
3467
|
-
|
3468
|
-
later.
|
3492
|
+
The compiler function will be called on matching elements when the page loads
|
3493
|
+
or when a matching fragment is [inserted via AJAX](/up.link) later.
|
3469
3494
|
|
3470
3495
|
@class up.syntax
|
3471
3496
|
*/
|
@@ -3474,7 +3499,7 @@ later.
|
|
3474
3499
|
var slice = [].slice;
|
3475
3500
|
|
3476
3501
|
up.syntax = (function($) {
|
3477
|
-
var DESTRUCTABLE_CLASS, DESTRUCTORS_KEY, addDestructor, applyCompiler, buildCompiler, clean, compile, compiler, compilers, data,
|
3502
|
+
var DESTRUCTABLE_CLASS, DESTRUCTORS_KEY, addDestructor, applyCompiler, buildCompiler, clean, compile, compiler, compilers, data, discoverDestructors, insertCompiler, macro, macros, reset, snapshot, u;
|
3478
3503
|
u = up.util;
|
3479
3504
|
DESTRUCTABLE_CLASS = 'up-destructable';
|
3480
3505
|
DESTRUCTORS_KEY = 'up-destructors';
|
@@ -3497,7 +3522,7 @@ later.
|
|
3497
3522
|
[Angular directives](https://docs.angularjs.org/guide/directive).
|
3498
3523
|
|
3499
3524
|
|
3500
|
-
|
3525
|
+
\#\#\# Integrating jQuery plugins
|
3501
3526
|
|
3502
3527
|
`up.compiler` is a great way to integrate jQuery plugins.
|
3503
3528
|
Let's say your Javascript plugin wants you to call `lightboxify()`
|
@@ -3514,7 +3539,7 @@ later.
|
|
3514
3539
|
});
|
3515
3540
|
|
3516
3541
|
|
3517
|
-
|
3542
|
+
\#\#\# Custom elements
|
3518
3543
|
|
3519
3544
|
You can use `up.compiler` to implement custom elements like this:
|
3520
3545
|
|
@@ -3528,7 +3553,7 @@ later.
|
|
3528
3553
|
});
|
3529
3554
|
|
3530
3555
|
|
3531
|
-
|
3556
|
+
\#\#\# Cleaning up after yourself
|
3532
3557
|
|
3533
3558
|
If your compiler returns a function, Unpoly will use this as a *destructor* to
|
3534
3559
|
clean up if the element leaves the DOM. Note that in Unpoly the same DOM ad Javascript environment
|
@@ -3537,7 +3562,7 @@ later.
|
|
3537
3562
|
|
3538
3563
|
You should clean up after yourself whenever your compilers have global
|
3539
3564
|
side effects, like a [`setInterval`](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval)
|
3540
|
-
or event handlers bound to the document root.
|
3565
|
+
or [event handlers bound to the document root](/up.on).
|
3541
3566
|
|
3542
3567
|
Here is a version of `<clock>` that updates
|
3543
3568
|
the time every second, and cleans up once it's done. Note how it returns
|
@@ -3563,7 +3588,7 @@ later.
|
|
3563
3588
|
of `<clock>` elements.
|
3564
3589
|
|
3565
3590
|
|
3566
|
-
|
3591
|
+
\#\#\# Attaching structured data
|
3567
3592
|
|
3568
3593
|
In case you want to attach structured data to the event you're observing,
|
3569
3594
|
you can serialize the data to JSON and put it into an `[up-data]` attribute.
|
@@ -3593,7 +3618,7 @@ later.
|
|
3593
3618
|
});
|
3594
3619
|
|
3595
3620
|
|
3596
|
-
|
3621
|
+
\#\#\# Migrating jQuery event handlers to `up.compiler`
|
3597
3622
|
|
3598
3623
|
Within the compiler, Unpoly will bind `this` to the
|
3599
3624
|
native DOM element to help you migrate your existing jQuery code to
|
@@ -3640,9 +3665,12 @@ later.
|
|
3640
3665
|
|
3641
3666
|
The function may return a destructor function that destroys the compiled
|
3642
3667
|
object before it is removed from the DOM. The destructor is supposed to
|
3643
|
-
clear global state
|
3668
|
+
[clear global state](/up.compiler#cleaning-up-after-yourself)
|
3669
|
+
such as timeouts and event handlers bound to the document.
|
3644
3670
|
The destructor is *not* expected to remove the element from the DOM, which
|
3645
3671
|
is already handled by [`up.destroy`](/up.destroy).
|
3672
|
+
|
3673
|
+
The function may also return an array of destructor functions.
|
3646
3674
|
@stable
|
3647
3675
|
*/
|
3648
3676
|
compiler = function() {
|
@@ -3656,7 +3684,7 @@ later.
|
|
3656
3684
|
|
3657
3685
|
You can use `up.macro` to register a compiler that sets other UJS attributes.
|
3658
3686
|
|
3659
|
-
|
3687
|
+
\#\#\# Example
|
3660
3688
|
|
3661
3689
|
You will sometimes find yourself setting the same combination of UJS attributes again and again:
|
3662
3690
|
|
@@ -3731,22 +3759,28 @@ later.
|
|
3731
3759
|
return queue.splice(index, 0, newCompiler);
|
3732
3760
|
};
|
3733
3761
|
applyCompiler = function(compiler, $jqueryElement, nativeElement) {
|
3734
|
-
var destructor, returnValue, value;
|
3762
|
+
var destructor, i, len, ref, results, returnValue, value;
|
3735
3763
|
up.puts((!compiler.isDefault ? "Compiling '%s' on %o" : void 0), compiler.selector, nativeElement);
|
3736
3764
|
if (compiler.keep) {
|
3737
3765
|
value = u.isString(compiler.keep) ? compiler.keep : '';
|
3738
3766
|
$jqueryElement.attr('up-keep', value);
|
3739
3767
|
}
|
3740
3768
|
returnValue = compiler.callback.apply(nativeElement, [$jqueryElement, data($jqueryElement)]);
|
3741
|
-
|
3742
|
-
|
3769
|
+
ref = discoverDestructors(returnValue);
|
3770
|
+
results = [];
|
3771
|
+
for (i = 0, len = ref.length; i < len; i++) {
|
3772
|
+
destructor = ref[i];
|
3773
|
+
results.push(addDestructor($jqueryElement, destructor));
|
3743
3774
|
}
|
3775
|
+
return results;
|
3744
3776
|
};
|
3745
|
-
|
3777
|
+
discoverDestructors = function(returnValue) {
|
3746
3778
|
if (u.isFunction(returnValue)) {
|
3747
|
-
return returnValue;
|
3779
|
+
return [returnValue];
|
3748
3780
|
} else if (u.isArray(returnValue) && u.all(returnValue, u.isFunction)) {
|
3749
|
-
return
|
3781
|
+
return returnValue;
|
3782
|
+
} else {
|
3783
|
+
return [];
|
3750
3784
|
}
|
3751
3785
|
};
|
3752
3786
|
addDestructor = function($jqueryElement, destructor) {
|
@@ -3838,7 +3872,7 @@ later.
|
|
3838
3872
|
|
3839
3873
|
Returns an empty object if the element has no `up-data` attribute.
|
3840
3874
|
|
3841
|
-
|
3875
|
+
\#\#\# Example
|
3842
3876
|
|
3843
3877
|
You have an element with JSON data serialized into an `up-data` attribute:
|
3844
3878
|
|
@@ -4190,7 +4224,7 @@ We need to work on this page:
|
|
4190
4224
|
Note that this will *not* call `location.back()`, but will set
|
4191
4225
|
the link's `up-href` attribute to the actual, previous URL.
|
4192
4226
|
|
4193
|
-
|
4227
|
+
\#\#\# Under the hood
|
4194
4228
|
|
4195
4229
|
This link ...
|
4196
4230
|
|
@@ -4319,13 +4353,13 @@ Unpoly will automatically be aware of sticky Bootstrap components such as
|
|
4319
4353
|
A "viewport" is an element that has scrollbars, e.g. `<body>` or
|
4320
4354
|
a container with `overflow-x: scroll`.
|
4321
4355
|
|
4322
|
-
|
4356
|
+
\#\#\# Example
|
4323
4357
|
|
4324
4358
|
This will scroll a `<div class="main">...</div>` to a Y-position of 100 pixels:
|
4325
4359
|
|
4326
4360
|
up.scroll('.main', 100);
|
4327
4361
|
|
4328
|
-
|
4362
|
+
\#\#\# Animating the scrolling motion
|
4329
4363
|
|
4330
4364
|
The scrolling can (optionally) be animated.
|
4331
4365
|
|
@@ -4450,9 +4484,9 @@ Unpoly will automatically be aware of sticky Bootstrap components such as
|
|
4450
4484
|
|
4451
4485
|
By default Unpoly will always reveal an element before
|
4452
4486
|
updating it with Javascript functions like [`up.replace`](/up.replace)
|
4453
|
-
or UJS behavior like [`[up-target]`](/up-target).
|
4487
|
+
or UJS behavior like [`[up-target]`](/a-up-target).
|
4454
4488
|
|
4455
|
-
|
4489
|
+
\#\#\# How Unpoly finds the viewport
|
4456
4490
|
|
4457
4491
|
The viewport (the container that is going to be scrolled)
|
4458
4492
|
is the closest parent of the element that is either:
|
@@ -4462,7 +4496,7 @@ Unpoly will automatically be aware of sticky Bootstrap components such as
|
|
4462
4496
|
- the `<body>` element
|
4463
4497
|
- an element matching the selector you have configured using `up.layout.config.viewports.push('my-custom-selector')`
|
4464
4498
|
|
4465
|
-
|
4499
|
+
\#\#\# Fixed elements obstruction the viewport
|
4466
4500
|
|
4467
4501
|
Many applications have a navigation bar fixed to the top or bottom,
|
4468
4502
|
obstructing the view on an element.
|
@@ -4747,7 +4781,7 @@ Unpoly will automatically be aware of sticky Bootstrap components such as
|
|
4747
4781
|
[`up.reveal`](/up.reveal) will always try to scroll the viewport closest
|
4748
4782
|
to the element that is being revealed. By default this is the `<body>` element.
|
4749
4783
|
|
4750
|
-
|
4784
|
+
\#\#\# Example
|
4751
4785
|
|
4752
4786
|
Here is an example for a layout for an e-mail client, showing a list of e-mails
|
4753
4787
|
on the left side and the e-mail text on the right side:
|
@@ -4797,7 +4831,7 @@ Unpoly will automatically be aware of sticky Bootstrap components such as
|
|
4797
4831
|
[`up.reveal`](/up.reveal) is aware of fixed elements and will scroll
|
4798
4832
|
the viewport far enough so the revealed element is fully visible.
|
4799
4833
|
|
4800
|
-
|
4834
|
+
\#\#\# Example
|
4801
4835
|
|
4802
4836
|
<div class="top-nav" up-fixed="top">...</div>
|
4803
4837
|
|
@@ -4812,7 +4846,7 @@ Unpoly will automatically be aware of sticky Bootstrap components such as
|
|
4812
4846
|
[`up.reveal`](/up.reveal) is aware of fixed elements and will scroll
|
4813
4847
|
the viewport far enough so the revealed element is fully visible.
|
4814
4848
|
|
4815
|
-
|
4849
|
+
\#\#\# Example
|
4816
4850
|
|
4817
4851
|
<div class="bottom-nav" up-fixed="bottom">...</div>
|
4818
4852
|
|
@@ -4827,7 +4861,7 @@ Unpoly will automatically be aware of sticky Bootstrap components such as
|
|
4827
4861
|
[`up.modal`](/up.modal) will move anchored elements to the left so they
|
4828
4862
|
don't appear to move when a modal dialog is opened or closed.
|
4829
4863
|
|
4830
|
-
|
4864
|
+
\#\#\# Example
|
4831
4865
|
|
4832
4866
|
<div class="bottom-nav" up-fixed="bottom">...</div>
|
4833
4867
|
|
@@ -4957,7 +4991,7 @@ are based on this module.
|
|
4957
4991
|
|
4958
4992
|
The UJS variant of this is the [`a[up-target]`](/a-up-target) selector.
|
4959
4993
|
|
4960
|
-
|
4994
|
+
\#\#\# Example
|
4961
4995
|
|
4962
4996
|
Let's say your curent HTML looks like this:
|
4963
4997
|
|
@@ -4982,7 +5016,7 @@ are based on this module.
|
|
4982
5016
|
Note how only `.two` has changed. The update for `.one` was
|
4983
5017
|
discarded, since it didn't match the selector.
|
4984
5018
|
|
4985
|
-
|
5019
|
+
\#\#\# Appending or prepending instead of replacing
|
4986
5020
|
|
4987
5021
|
By default Unpoly will replace the given selector with the same
|
4988
5022
|
selector from a freshly fetched page. Instead of replacing you
|
@@ -5003,7 +5037,7 @@ are based on this module.
|
|
5003
5037
|
|
5004
5038
|
up.replace('.tasks:after', '/page/2')
|
5005
5039
|
|
5006
|
-
|
5040
|
+
\#\#\# Setting the window title from the server
|
5007
5041
|
|
5008
5042
|
If the `replace` call changes history, the document title will be set
|
5009
5043
|
to the contents of a `<title>` tag in the response.
|
@@ -5011,7 +5045,7 @@ are based on this module.
|
|
5011
5045
|
The server can also change the document title by setting
|
5012
5046
|
an `X-Up-Title` header in the response.
|
5013
5047
|
|
5014
|
-
|
5048
|
+
\#\#\# Optimizing response rendering
|
5015
5049
|
|
5016
5050
|
The server is free to optimize Unpoly requests by only rendering the HTML fragment
|
5017
5051
|
that is being updated. The request's `X-Up-Target` header will contain
|
@@ -5020,7 +5054,7 @@ are based on this module.
|
|
5020
5054
|
If you are using the `unpoly-rails` gem you can also access the selector via
|
5021
5055
|
`up.target` in all controllers, views and helpers.
|
5022
5056
|
|
5023
|
-
|
5057
|
+
\#\#\# Events
|
5024
5058
|
|
5025
5059
|
Unpoly will emit [`up:fragment:destroyed`](/up:fragment:destroyed) on the element
|
5026
5060
|
that was replaced and [`up:fragment:inserted`](/up:fragment:inserted) on the new
|
@@ -5194,7 +5228,7 @@ are based on this module.
|
|
5194
5228
|
Updates a selector on the current page with the
|
5195
5229
|
same selector from the given HTML string.
|
5196
5230
|
|
5197
|
-
|
5231
|
+
\#\#\# Example
|
5198
5232
|
|
5199
5233
|
Let's say your curent HTML looks like this:
|
5200
5234
|
|
@@ -5461,7 +5495,7 @@ are based on this module.
|
|
5461
5495
|
|
5462
5496
|
Emits events [`up:fragment:keep`](/up:fragment:keep) and [`up:fragment:kept`](/up:fragment:kept).
|
5463
5497
|
|
5464
|
-
|
5498
|
+
\#\#\# Controlling if an element will be kept
|
5465
5499
|
|
5466
5500
|
Unpoly will **only** keep an existing element if:
|
5467
5501
|
|
@@ -5615,7 +5649,7 @@ are based on this module.
|
|
5615
5649
|
When a page fragment has been [inserted or updated](/up.replace),
|
5616
5650
|
this event is [emitted](/up.emit) on the fragment.
|
5617
5651
|
|
5618
|
-
|
5652
|
+
\#\#\# Example
|
5619
5653
|
|
5620
5654
|
up.on('up:fragment:inserted', function(event, $fragment) {
|
5621
5655
|
console.log("Looks like we have a new %o!", $fragment);
|
@@ -5827,7 +5861,7 @@ are based on this module.
|
|
5827
5861
|
/**
|
5828
5862
|
Replaces the given element with a fresh copy fetched from the server.
|
5829
5863
|
|
5830
|
-
|
5864
|
+
\#\#\# Example
|
5831
5865
|
|
5832
5866
|
up.on('new-mail', function() {
|
5833
5867
|
up.reload('.inbox');
|
@@ -5892,35 +5926,32 @@ are based on this module.
|
|
5892
5926
|
Animation
|
5893
5927
|
=========
|
5894
5928
|
|
5895
|
-
Whenever you update a page fragment
|
5896
|
-
[`up.replace`](/up.replace) or UJS attributes like [`up-target`](/up-target))
|
5897
|
-
you can animate the change.
|
5929
|
+
Whenever you [update a page fragment](/up-link) you can animate the change.
|
5898
5930
|
|
5899
|
-
|
5900
|
-
from the server
|
5901
|
-
to smoothly fade out the old
|
5931
|
+
Let's say you are using an [`up-target`](/a-up-target) link to update an element
|
5932
|
+
with content from the server. You can add an attribute [`up-transition`](/a-up-target#up-transition)
|
5933
|
+
to smoothly fade out the old element while fading in the new element:
|
5902
5934
|
|
5903
5935
|
<a href="/users" up-target=".list" up-transition="cross-fade">Show users</a>
|
5904
5936
|
|
5905
|
-
Transitions vs. animations
|
5906
|
-
--------------------------
|
5937
|
+
\#\#\# Transitions vs. animations
|
5907
5938
|
|
5908
|
-
When we morph between an old
|
5939
|
+
When we morph between an old and a new element, we call it a *transition*.
|
5909
5940
|
In contrast, when we animate a new element without simultaneously removing an
|
5910
5941
|
old element, we call it an *animation*.
|
5911
5942
|
|
5912
|
-
An example for an animation is opening a new dialog
|
5913
|
-
|
5943
|
+
An example for an animation is opening a new dialog. We can animate the appearance
|
5944
|
+
of the dialog by adding an [`up-animation`](/up-modal#up-animation) attribute to the opening link:
|
5914
5945
|
|
5915
5946
|
<a href="/users" up-modal=".list" up-animation="move-from-top">Show users</a>
|
5916
5947
|
|
5917
|
-
|
5918
|
-
-------------------------------------
|
5948
|
+
\#\#\# Which animations are available?
|
5919
5949
|
|
5920
|
-
Unpoly ships with a number of predefined
|
5921
|
-
and [
|
5922
|
-
|
5923
|
-
|
5950
|
+
Unpoly ships with a number of [predefined transitions](/up.morph#named-transitions)
|
5951
|
+
and [predefined animations](/up.animate#named-animations).
|
5952
|
+
|
5953
|
+
You can define custom animations using [`up.transition`](/up.transition) and
|
5954
|
+
[`up.animation`](/up.animation).
|
5924
5955
|
|
5925
5956
|
@class up.motion
|
5926
5957
|
*/
|
@@ -5990,7 +6021,7 @@ or [transitions](/up.transition) using Javascript or CSS.
|
|
5990
6021
|
/**
|
5991
6022
|
Applies the given animation to the given element.
|
5992
6023
|
|
5993
|
-
|
6024
|
+
\#\#\# Example
|
5994
6025
|
|
5995
6026
|
up.animate('.warning', 'fade-in');
|
5996
6027
|
|
@@ -6002,7 +6033,7 @@ or [transitions](/up.transition) using Javascript or CSS.
|
|
6002
6033
|
easing: 'linear'
|
6003
6034
|
});
|
6004
6035
|
|
6005
|
-
|
6036
|
+
\#\#\# Named animations
|
6006
6037
|
|
6007
6038
|
The following animations are pre-defined:
|
6008
6039
|
|
@@ -6020,7 +6051,7 @@ or [transitions](/up.transition) using Javascript or CSS.
|
|
6020
6051
|
|
6021
6052
|
You can define additional named animations using [`up.animation`](/up.animation).
|
6022
6053
|
|
6023
|
-
|
6054
|
+
\#\#\# Animating CSS properties directly
|
6024
6055
|
|
6025
6056
|
By passing an object instead of an animation name, you can animate
|
6026
6057
|
the CSS properties of the given element:
|
@@ -6029,7 +6060,7 @@ or [transitions](/up.transition) using Javascript or CSS.
|
|
6029
6060
|
$warning.css({ opacity: 0 });
|
6030
6061
|
up.animate($warning, { opacity: 1 });
|
6031
6062
|
|
6032
|
-
|
6063
|
+
\#\#\# Multiple animations on the same element
|
6033
6064
|
|
6034
6065
|
Unpoly doesn't allow more than one concurrent animation on the same element.
|
6035
6066
|
|
@@ -6200,7 +6231,7 @@ or [transitions](/up.transition) using Javascript or CSS.
|
|
6200
6231
|
Note that the transition does not remove any elements from the DOM.
|
6201
6232
|
The first element will remain in the DOM, albeit hidden using `display: none`.
|
6202
6233
|
|
6203
|
-
|
6234
|
+
\#\#\# Named transitions
|
6204
6235
|
|
6205
6236
|
The following transitions are pre-defined:
|
6206
6237
|
|
@@ -6219,7 +6250,7 @@ or [transitions](/up.transition) using Javascript or CSS.
|
|
6219
6250
|
- `move-to-bottom/fade-in`
|
6220
6251
|
- `move-to-left/move-from-top`
|
6221
6252
|
|
6222
|
-
|
6253
|
+
\#\#\# Implementation details
|
6223
6254
|
|
6224
6255
|
During a transition both the old and new element occupy
|
6225
6256
|
the same position on the screen.
|
@@ -6789,7 +6820,7 @@ the user performs the click.
|
|
6789
6820
|
Only requests with a method of `GET`, `OPTIONS` and `HEAD`
|
6790
6821
|
are considered to be read-only.
|
6791
6822
|
|
6792
|
-
|
6823
|
+
\#\#\# Example
|
6793
6824
|
|
6794
6825
|
up.ajax('/search', data: { query: 'sunshine' }).then(function(data, status, xhr) {
|
6795
6826
|
console.log('The response body is %o', data);
|
@@ -6797,7 +6828,7 @@ the user performs the click.
|
|
6797
6828
|
console.error('The request failed');
|
6798
6829
|
});
|
6799
6830
|
|
6800
|
-
|
6831
|
+
\#\#\# Events
|
6801
6832
|
|
6802
6833
|
If a network connection is attempted, the proxy will emit
|
6803
6834
|
a [`up:proxy:load`](/up:proxy:load) event with the `request` as its argument.
|
@@ -6926,7 +6957,7 @@ the user performs the click.
|
|
6926
6957
|
waiting, **no** additional `up:proxy:slow` events will be triggered.
|
6927
6958
|
|
6928
6959
|
|
6929
|
-
|
6960
|
+
\#\#\# Spinners
|
6930
6961
|
|
6931
6962
|
You can [listen](/up.on) to the `up:proxy:slow`
|
6932
6963
|
and [`up:proxy:recover`](/up:proxy:recover) events to implement a spinner
|
@@ -7225,13 +7256,12 @@ Standard HTML links are a poor fit for modern applications:
|
|
7225
7256
|
- The user sees a "flash" as the browser loads and renders the new page,
|
7226
7257
|
even if large portions of the old and new page are the same (navigation, layout, etc.).
|
7227
7258
|
|
7228
|
-
Unpoly fixes this by letting you annotate links with an [`up-target`](/up-target)
|
7259
|
+
Unpoly fixes this by letting you annotate links with an [`up-target`](/a-up-target)
|
7229
7260
|
attribute. The value of this attribute is a CSS selector that indicates which page
|
7230
7261
|
fragment to update. The rest of the page will remain unchanged.
|
7231
7262
|
|
7232
7263
|
|
7233
|
-
Example
|
7234
|
-
-------
|
7264
|
+
\#\#\# Example
|
7235
7265
|
|
7236
7266
|
Let's say we are rendering three pages with a tabbed navigation to switch between screens:
|
7237
7267
|
|
@@ -7275,13 +7305,13 @@ with an `up-target` attribute:
|
|
7275
7305
|
|
7276
7306
|
Note that instead of `article` you can use any other CSS selector like `#main .article`.
|
7277
7307
|
|
7278
|
-
With these [`up-target`](/up-target) annotations Unpoly only updates the targeted part of the screen.
|
7308
|
+
With these [`up-target`](/a-up-target) annotations Unpoly only updates the targeted part of the screen.
|
7279
7309
|
The Javascript environment will persist and the user will not see a white flash while the
|
7280
7310
|
new page is loading.
|
7281
7311
|
|
7282
7312
|
|
7283
|
-
Read on
|
7284
|
-
|
7313
|
+
\#\#\# Read on
|
7314
|
+
|
7285
7315
|
- You can [animate page transitions](/up.motion) by definining animations for fragments as they enter or leave the screen.
|
7286
7316
|
- The `up-target` mechanism also works with [forms](/up.form).
|
7287
7317
|
- As you switch through pages, Unpoly will [update your browser's location bar and history](/up.history)
|
@@ -7454,18 +7484,16 @@ Read on
|
|
7454
7484
|
var handlerWithActiveMark;
|
7455
7485
|
followVariantSelectors.push(selector);
|
7456
7486
|
handlerWithActiveMark = function($link) {
|
7457
|
-
return up.navigation.
|
7458
|
-
enlarge: true
|
7459
|
-
}, function() {
|
7487
|
+
return up.navigation.start($link, function() {
|
7460
7488
|
return handler($link);
|
7461
7489
|
});
|
7462
7490
|
};
|
7463
7491
|
up.on('click', "a" + selector + ", [up-href]" + selector, function(event, $link) {
|
7464
7492
|
if (shouldProcessLinkEvent(event, $link)) {
|
7465
7493
|
if ($link.is('[up-instant]')) {
|
7466
|
-
return
|
7494
|
+
return up.bus.haltEvent(event);
|
7467
7495
|
} else {
|
7468
|
-
|
7496
|
+
up.bus.consumeAction(event);
|
7469
7497
|
return handlerWithActiveMark($link);
|
7470
7498
|
}
|
7471
7499
|
} else {
|
@@ -7474,7 +7502,7 @@ Read on
|
|
7474
7502
|
});
|
7475
7503
|
return up.on('mousedown', "a" + selector + "[up-instant], [up-href]" + selector + "[up-instant]", function(event, $link) {
|
7476
7504
|
if (shouldProcessLinkEvent(event, $link)) {
|
7477
|
-
|
7505
|
+
up.bus.consumeAction(event);
|
7478
7506
|
return handlerWithActiveMark($link);
|
7479
7507
|
}
|
7480
7508
|
});
|
@@ -7508,7 +7536,7 @@ Read on
|
|
7508
7536
|
|
7509
7537
|
<a href="/posts/5" up-target=".main">Read post</a>
|
7510
7538
|
|
7511
|
-
|
7539
|
+
\#\#\# Updating multiple fragments
|
7512
7540
|
|
7513
7541
|
You can update multiple fragments from a single request by separating
|
7514
7542
|
separators with a comma (like in CSS). E.g. if opening a post should
|
@@ -7517,7 +7545,7 @@ Read on
|
|
7517
7545
|
|
7518
7546
|
<a href="/posts/5" up-target=".main, .unread-count">Read post</a>
|
7519
7547
|
|
7520
|
-
|
7548
|
+
\#\#\# Appending or prepending instead of replacing
|
7521
7549
|
|
7522
7550
|
By default Unpoly will replace the given selector with the same
|
7523
7551
|
selector from a freshly fetched page. Instead of replacing you
|
@@ -7539,7 +7567,7 @@ Read on
|
|
7539
7567
|
Load more tasks
|
7540
7568
|
</a>
|
7541
7569
|
|
7542
|
-
|
7570
|
+
\#\#\# Following elements that are no links
|
7543
7571
|
|
7544
7572
|
You can also use `[up-target]` to turn an arbitrary element into a link.
|
7545
7573
|
In this case, put the link's destination into the `up-href` attribute:
|
@@ -7552,13 +7580,18 @@ Read on
|
|
7552
7580
|
@selector a[up-target]
|
7553
7581
|
@param {String} up-target
|
7554
7582
|
The CSS selector to replace
|
7583
|
+
@param {String} [up-method='get']
|
7584
|
+
The HTTP method to use for the request.
|
7585
|
+
@param {String} [up-transition='none']
|
7586
|
+
The [transition](/up.motion) to use for morphing between the old and new elements.
|
7555
7587
|
@param [up-fail-target='body']
|
7556
7588
|
The selector to replace if the server responds with a non-200 status code.
|
7589
|
+
@param {String} [up-fail-transition='none']
|
7590
|
+
The [transition](/up.motion) to use for morphing between the old and new elements
|
7591
|
+
when the server responds with a non-200 status code.
|
7557
7592
|
@param {String} [up-href]
|
7558
7593
|
The destination URL to follow.
|
7559
7594
|
If omitted, the the link's `href` attribute will be used.
|
7560
|
-
@param {String} [up-method='get']
|
7561
|
-
The HTTP method to use for the request.
|
7562
7595
|
@param {String} [up-confirm]
|
7563
7596
|
A message that will be displayed in a cancelable confirmation dialog
|
7564
7597
|
before the link is followed.
|
@@ -7618,11 +7651,11 @@ Read on
|
|
7618
7651
|
To only update a fragment instead of the entire page, see
|
7619
7652
|
[`a[up-target]`](/a-up-target).
|
7620
7653
|
|
7621
|
-
|
7654
|
+
\#\#\# Example
|
7622
7655
|
|
7623
7656
|
<a href="/users" up-follow>User list</a>
|
7624
7657
|
|
7625
|
-
|
7658
|
+
\#\#\# Turn any element into a link
|
7626
7659
|
|
7627
7660
|
You can also use `[up-follow]` to turn an arbitrary element into a link.
|
7628
7661
|
In this case, put the link's destination into the `up-href` attribute:
|
@@ -7633,13 +7666,19 @@ Read on
|
|
7633
7666
|
opening the destination in a new tab.
|
7634
7667
|
|
7635
7668
|
@selector a[up-follow]
|
7669
|
+
|
7670
|
+
@param {String} [up-method='get']
|
7671
|
+
The HTTP method to use for the request.
|
7672
|
+
@param {String} [up-transition='none']
|
7673
|
+
The [transition](/up.motion) to use for morphing between the old and new elements.
|
7636
7674
|
@param [up-fail-target='body']
|
7637
7675
|
The selector to replace if the server responds with a non-200 status code.
|
7676
|
+
@param {String} [up-fail-transition='none']
|
7677
|
+
The [transition](/up.motion) to use for morphing between the old and new elements
|
7678
|
+
when the server responds with a non-200 status code.
|
7638
7679
|
@param [up-href]
|
7639
7680
|
The destination URL to follow.
|
7640
7681
|
If omitted, the the link's `href` attribute will be used.
|
7641
|
-
@param {String} [up-method='get']
|
7642
|
-
The HTTP method to use for the request.
|
7643
7682
|
@param {String} [up-confirm]
|
7644
7683
|
A message that will be displayed in a cancelable confirmation dialog
|
7645
7684
|
before the link is followed.
|
@@ -7662,7 +7701,7 @@ Read on
|
|
7662
7701
|
|
7663
7702
|
This is done by:
|
7664
7703
|
|
7665
|
-
- [Following the link through AJAX](/up-target) instead of a full page load
|
7704
|
+
- [Following the link through AJAX](/a-up-target) instead of a full page load
|
7666
7705
|
- [Preloading the link's destination URL](/up-preload)
|
7667
7706
|
- [Triggering the link on `mousedown`](/up-instant) instead of on `click`
|
7668
7707
|
|
@@ -7700,9 +7739,9 @@ Read on
|
|
7700
7739
|
in order to enlarge the link's click area.
|
7701
7740
|
|
7702
7741
|
`up-expand` honors all the UJS behavior in expanded links
|
7703
|
-
([`up-target`](/up-target), [`up-instant`](/up-instant), [`up-preload`](/up-preload), etc.).
|
7742
|
+
([`up-target`](/a-up-target), [`up-instant`](/up-instant), [`up-preload`](/up-preload), etc.).
|
7704
7743
|
|
7705
|
-
|
7744
|
+
\#\#\# Example
|
7706
7745
|
|
7707
7746
|
<div class="notification" up-expand>
|
7708
7747
|
Record was saved!
|
@@ -7714,7 +7753,7 @@ Read on
|
|
7714
7753
|
|
7715
7754
|
`up-expand` also expands links that open [modals](/up.modal) or [popups](/up.popup).
|
7716
7755
|
|
7717
|
-
|
7756
|
+
\#\#\# Elements with multiple contained links
|
7718
7757
|
|
7719
7758
|
If a container contains more than one link, you can set the value of the
|
7720
7759
|
`up-expand` attribute to a CSS selector to define which link should be expanded:
|
@@ -7922,14 +7961,14 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
7922
7961
|
return u.unresolvablePromise();
|
7923
7962
|
}
|
7924
7963
|
}
|
7925
|
-
up.navigation.
|
7964
|
+
up.navigation.start($form);
|
7926
7965
|
if (!(canAjaxSubmit && canHistoryOption)) {
|
7927
7966
|
$form.get(0).submit();
|
7928
7967
|
return u.unresolvablePromise();
|
7929
7968
|
}
|
7930
7969
|
promise = up.replace(target, url, options);
|
7931
7970
|
promise.always(function() {
|
7932
|
-
return up.navigation.
|
7971
|
+
return up.navigation.stop($form);
|
7933
7972
|
});
|
7934
7973
|
return promise;
|
7935
7974
|
};
|
@@ -7941,7 +7980,7 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
7941
7980
|
|
7942
7981
|
The UJS variant of this is the [`up-observe`](/up-observe) attribute.
|
7943
7982
|
|
7944
|
-
|
7983
|
+
\#\#\# Example
|
7945
7984
|
|
7946
7985
|
The following would submit the form whenever the
|
7947
7986
|
text field value changes:
|
@@ -7954,7 +7993,7 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
7954
7993
|
pass, a `<form>` or any container that contains form fields.
|
7955
7994
|
The callback will be run if any of the given fields change.
|
7956
7995
|
|
7957
|
-
|
7996
|
+
\#\#\# Preventing concurrency
|
7958
7997
|
|
7959
7998
|
Firing asynchronous code after a form field can cause
|
7960
7999
|
[concurrency issues](https://makandracards.com/makandra/961-concurrency-issues-with-find-as-you-type-boxes).
|
@@ -7964,7 +8003,7 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
7964
8003
|
To take advantage of this, your callback code must return a promise.
|
7965
8004
|
Note that all asynchronous Unpoly functions return promises.
|
7966
8005
|
|
7967
|
-
|
8006
|
+
\#\#\# Throttling
|
7968
8007
|
|
7969
8008
|
If you are concerned about fast typists causing too much
|
7970
8009
|
load on your server, you can use a `delay` option to wait
|
@@ -8098,7 +8137,7 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
8098
8137
|
return observe(selectorOrElement, options, function(value, $field) {
|
8099
8138
|
var $form;
|
8100
8139
|
$form = $field.closest('form');
|
8101
|
-
return up.navigation.
|
8140
|
+
return up.navigation.start($field, function() {
|
8102
8141
|
return submit($form);
|
8103
8142
|
});
|
8104
8143
|
});
|
@@ -8134,7 +8173,7 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
8134
8173
|
See the documentation for [`[up-validate]`](/up-validate) for more information
|
8135
8174
|
on how server-side validation works in Unpoly.
|
8136
8175
|
|
8137
|
-
|
8176
|
+
\#\#\# Example
|
8138
8177
|
|
8139
8178
|
up.validate('input[name=email]', { target: '.email-errors' })
|
8140
8179
|
|
@@ -8274,7 +8313,7 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
8274
8313
|
|
8275
8314
|
The programmatic variant of this is the [`up.submit`](/up.submit) function.
|
8276
8315
|
|
8277
|
-
|
8316
|
+
\#\#\# Failed submission
|
8278
8317
|
|
8279
8318
|
When the server was unable to save the form due to invalid data,
|
8280
8319
|
it will usually re-render an updated copy of the form with
|
@@ -8307,7 +8346,7 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
8307
8346
|
[`up-validate`](/up-validate) attribute to perform server-side
|
8308
8347
|
validations while the user is completing fields.
|
8309
8348
|
|
8310
|
-
|
8349
|
+
\#\#\# Redirects
|
8311
8350
|
|
8312
8351
|
Unpoly requires two additional response headers to detect redirects,
|
8313
8352
|
which are otherwise undetectable for an AJAX client.
|
@@ -8319,7 +8358,7 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
8319
8358
|
If you are using Unpoly via the `unpoly-rails` gem, these headers
|
8320
8359
|
are set automatically for every request.
|
8321
8360
|
|
8322
|
-
|
8361
|
+
\#\#\# Giving feedback while the form is processing
|
8323
8362
|
|
8324
8363
|
The `<form>` element will be assigned a CSS class `up-active` while
|
8325
8364
|
the submission is loading.
|
@@ -8366,7 +8405,7 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
8366
8405
|
@stable
|
8367
8406
|
*/
|
8368
8407
|
up.on('submit', 'form[up-target]', function(event, $form) {
|
8369
|
-
|
8408
|
+
up.bus.consumeAction(event);
|
8370
8409
|
return submit($form);
|
8371
8410
|
});
|
8372
8411
|
|
@@ -8377,7 +8416,7 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
8377
8416
|
|
8378
8417
|
The programmatic variant of this is the [`up.validate`](/up.validate) function.
|
8379
8418
|
|
8380
|
-
|
8419
|
+
\#\#\# Example
|
8381
8420
|
|
8382
8421
|
Let's look at a standard registration form that asks for an e-mail and password:
|
8383
8422
|
|
@@ -8458,7 +8497,7 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
8458
8497
|
The `<label>` around the e-mail field is now updated to have the `has-error`
|
8459
8498
|
class and display the validation message.
|
8460
8499
|
|
8461
|
-
|
8500
|
+
\#\#\# How validation results are displayed
|
8462
8501
|
|
8463
8502
|
Although the server will usually respond to a validation with a complete,
|
8464
8503
|
fresh copy of the form, Unpoly will by default not update the entire form.
|
@@ -8482,7 +8521,7 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
8482
8521
|
<input type="text" name="email" up-validate=".email-errors">
|
8483
8522
|
<span class="email-errors"></span>
|
8484
8523
|
|
8485
|
-
|
8524
|
+
\#\#\# Updating dependent fields
|
8486
8525
|
|
8487
8526
|
The `[up-validate]` behavior is also a great way to partially update a form
|
8488
8527
|
when one fields depends on the value of another field.
|
@@ -8519,7 +8558,7 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
8519
8558
|
/**
|
8520
8559
|
Show or hide part of a form if certain options are selected or boxes are checked.
|
8521
8560
|
|
8522
|
-
|
8561
|
+
\#\#\# Example
|
8523
8562
|
|
8524
8563
|
The triggering input gets an `up-switch` attribute with a selector for the elements to show or hide:
|
8525
8564
|
|
@@ -8599,7 +8638,7 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
8599
8638
|
|
8600
8639
|
The programmatic variant of this is the [`up.observe`](/up.observe) function.
|
8601
8640
|
|
8602
|
-
|
8641
|
+
\#\#\# Example
|
8603
8642
|
|
8604
8643
|
The following would run a global `showSuggestions(value)` function
|
8605
8644
|
whenever the `<input>` changes:
|
@@ -8608,7 +8647,7 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
8608
8647
|
<input type="query" up-observe="showSuggestions(value)">
|
8609
8648
|
</form>
|
8610
8649
|
|
8611
|
-
|
8650
|
+
\#\#\# Callback context
|
8612
8651
|
|
8613
8652
|
The script given to `up-observe` runs with the following context:
|
8614
8653
|
|
@@ -8637,7 +8676,7 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
8637
8676
|
|
8638
8677
|
The programmatic variant of this is the [`up.autosubmit`](/up.autosubmit) function.
|
8639
8678
|
|
8640
|
-
|
8679
|
+
\#\#\# Example
|
8641
8680
|
|
8642
8681
|
The following would submit the form whenever the
|
8643
8682
|
text field value changes:
|
@@ -8696,7 +8735,7 @@ or call the Javascript function [`up.popup.attach`](/up.popup.attach).
|
|
8696
8735
|
|
8697
8736
|
For modal dialogs see [up.modal](/up.modal) instead.
|
8698
8737
|
|
8699
|
-
|
8738
|
+
\#\#\# Customizing the popup design
|
8700
8739
|
|
8701
8740
|
Loading the Unpoly stylesheet will give you a minimal popup design:
|
8702
8741
|
|
@@ -8712,7 +8751,7 @@ By default the popup uses the following DOM structure:
|
|
8712
8751
|
...
|
8713
8752
|
</div>
|
8714
8753
|
|
8715
|
-
|
8754
|
+
\#\#\# Closing behavior
|
8716
8755
|
|
8717
8756
|
The popup closes when the user clicks anywhere outside the popup area.
|
8718
8757
|
|
@@ -8870,14 +8909,22 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
8870
8909
|
Emits events [`up:popup:open`](/up:popup:open) and [`up:popup:opened`](/up:popup:opened).
|
8871
8910
|
|
8872
8911
|
@function up.popup.attach
|
8873
|
-
@param {Element|jQuery|String}
|
8912
|
+
@param {Element|jQuery|String} anchor
|
8913
|
+
The element to which the popup will be attached.
|
8874
8914
|
@param {String} [options.url]
|
8915
|
+
The URL from which to fetch the popup contents.
|
8916
|
+
|
8917
|
+
If omitted, the `href` or `up-href` attribute of the anchor element will be used.
|
8918
|
+
|
8919
|
+
Will be ignored if `options.html` is given.
|
8875
8920
|
@param {String} [options.target]
|
8876
8921
|
A CSS selector that will be extracted from the response and placed into the popup.
|
8877
8922
|
@param {String} [options.position='bottom-right']
|
8878
8923
|
Defines where the popup is attached to the opening element.
|
8879
8924
|
|
8880
8925
|
Valid values are `bottom-right`, `bottom-left`, `top-right` and `top-left`.
|
8926
|
+
@param {String} [options.html]
|
8927
|
+
A string of HTML from which to extract the popup contents. No network request will be made.
|
8881
8928
|
@param {String} [options.confirm]
|
8882
8929
|
A message that will be displayed in a cancelable confirmation dialog
|
8883
8930
|
before the modal is being opened.
|
@@ -9122,7 +9169,7 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
9122
9169
|
return attachAsap($link);
|
9123
9170
|
}
|
9124
9171
|
});
|
9125
|
-
up.on('
|
9172
|
+
up.on('click up:action:consumed', function(event) {
|
9126
9173
|
var $target;
|
9127
9174
|
$target = $(event.target);
|
9128
9175
|
if (!$target.closest('.up-popup, [up-popup]').length) {
|
@@ -9158,7 +9205,7 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
9158
9205
|
up.on('click', '[up-close]', function(event, $element) {
|
9159
9206
|
if (contains($element)) {
|
9160
9207
|
closeAsap();
|
9161
|
-
return
|
9208
|
+
return up.bus.consumeAction(event);
|
9162
9209
|
}
|
9163
9210
|
});
|
9164
9211
|
up.on('up:framework:reset', reset);
|
@@ -9184,28 +9231,40 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
9184
9231
|
Modal dialogs
|
9185
9232
|
=============
|
9186
9233
|
|
9187
|
-
Instead of [linking to a page fragment](/up.link), you can choose
|
9188
|
-
|
9189
|
-
open in the background and reappear once the modal is closed.
|
9234
|
+
Instead of [linking to a page fragment](/up.link), you can choose to show a fragment
|
9235
|
+
in a modal dialog. The existing page will remain open in the background.
|
9190
9236
|
|
9191
|
-
To open a modal, add an [`up-modal`
|
9192
|
-
|
9193
|
-
|
9194
|
-
|
9195
|
-
|
9237
|
+
To open a modal, add an [`up-modal`](/up-modal) attribute to a link:
|
9238
|
+
|
9239
|
+
<a href="/blogs" up-modal=".blog-list">Switch blog</a>
|
9240
|
+
|
9241
|
+
When this link is clicked, Unpoly will request the path `/blogs` and extract
|
9242
|
+
an element matching the selector `.blog-list` from the response. The matching element
|
9243
|
+
will then be placed in a modal dialog.
|
9244
|
+
|
9245
|
+
|
9246
|
+
\#\#\# Closing behavior
|
9247
|
+
|
9248
|
+
By default the dialog automatically closes
|
9249
|
+
*when a link inside a modal changes a fragment behind the modal*.
|
9250
|
+
This is useful to have the dialog interact with the page that
|
9251
|
+
opened it, e.g. by updating parts of a larger form or by signing in a user
|
9252
|
+
and revealing additional information.
|
9253
|
+
|
9254
|
+
To disable this behavior, give the opening link an [`up-sticky`](/up-modal#up-sticky) attribute:
|
9196
9255
|
|
9197
9256
|
|
9198
|
-
|
9257
|
+
\#\#\# Customizing the dialog design
|
9199
9258
|
|
9200
|
-
|
9259
|
+
Dialogs have a minimal default design:
|
9201
9260
|
|
9202
|
-
-
|
9203
|
-
- There is a a subtle box shadow around the dialog
|
9261
|
+
- Contents are displayed in a white box with a subtle box shadow
|
9204
9262
|
- The box will grow to fit the dialog contents, but never grow larger than the screen
|
9205
|
-
- The box is placed over a semi-transparent
|
9263
|
+
- The box is placed over a semi-transparent backdrop to dim the rest of the page
|
9206
9264
|
- There is a button to close the dialog in the top-right corner
|
9207
9265
|
|
9208
|
-
The easiest way to change how the dialog looks is by overriding the
|
9266
|
+
The easiest way to change how the dialog looks is by overriding the
|
9267
|
+
[default CSS styles](https://github.com/unpoly/unpoly/blob/master/lib/assets/stylesheets/up/modal.css.sass).
|
9209
9268
|
|
9210
9269
|
By default the dialog uses the following DOM structure:
|
9211
9270
|
|
@@ -9214,28 +9273,15 @@ By default the dialog uses the following DOM structure:
|
|
9214
9273
|
<div class="up-modal-viewport">
|
9215
9274
|
<div class="up-modal-dialog">
|
9216
9275
|
<div class="up-modal-content">
|
9217
|
-
|
9276
|
+
<!-- the matching element will be placed here -->
|
9218
9277
|
</div>
|
9219
9278
|
<div class="up-modal-close" up-close>X</div>
|
9220
9279
|
</div>
|
9221
9280
|
</div>
|
9222
9281
|
</div>
|
9223
9282
|
|
9224
|
-
|
9225
|
-
|
9226
|
-
|
9227
|
-
|
9228
|
-
\#\#\#\# Closing behavior
|
9229
|
-
|
9230
|
-
By default the dialog automatically closes
|
9231
|
-
*when a link inside a modal changes a fragment behind the modal*.
|
9232
|
-
This is useful to have the dialog interact with the page that
|
9233
|
-
opened it, e.g. by updating parts of a larger form or by signing in a user
|
9234
|
-
and revealing additional information.
|
9235
|
-
|
9236
|
-
To disable this behavior, give the opening link an `up-sticky` attribute:
|
9237
|
-
|
9238
|
-
<a href="/settings" up-modal=".options" up-sticky>Settings</a>
|
9283
|
+
You can change this structure by setting [`up.modal.config.template`](/up.modal.config#config.template) to a new template string
|
9284
|
+
or function.
|
9239
9285
|
|
9240
9286
|
|
9241
9287
|
@class up.modal
|
@@ -9253,7 +9299,7 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
9253
9299
|
@param {String} [config.history=true]
|
9254
9300
|
Whether opening a modal will add a browser history entry.
|
9255
9301
|
@param {Number} [config.width]
|
9256
|
-
The width of the dialog as a CSS value like `'400px'` or `50
|
9302
|
+
The width of the dialog as a CSS value like `'400px'` or `'50%'`.
|
9257
9303
|
|
9258
9304
|
Defaults to `undefined`, meaning that the dialog will grow to fit its contents
|
9259
9305
|
until it reaches `config.maxWidth`. Leaving this as `undefined` will
|
@@ -9793,7 +9839,7 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
9793
9839
|
/**
|
9794
9840
|
Register a new modal variant with its own default configuration, CSS or HTML template.
|
9795
9841
|
|
9796
|
-
|
9842
|
+
\#\#\# Example
|
9797
9843
|
|
9798
9844
|
Let's implement a drawer that slides in from the right:
|
9799
9845
|
|
@@ -9914,13 +9960,14 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
9914
9960
|
up.link.onAction('[up-modal]', function($link) {
|
9915
9961
|
return followAsap($link);
|
9916
9962
|
});
|
9917
|
-
up.on('click',
|
9963
|
+
up.on('click', function(event) {
|
9918
9964
|
var $target;
|
9919
9965
|
if (!state.closable) {
|
9920
9966
|
return;
|
9921
9967
|
}
|
9922
9968
|
$target = $(event.target);
|
9923
9969
|
if (!($target.closest('.up-modal-dialog').length || $target.closest('[up-modal]').length)) {
|
9970
|
+
up.bus.consumeAction(event);
|
9924
9971
|
return closeAsap();
|
9925
9972
|
}
|
9926
9973
|
});
|
@@ -9956,7 +10003,7 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
9956
10003
|
up.on('click', '[up-close]', function(event, $element) {
|
9957
10004
|
if (contains($element)) {
|
9958
10005
|
closeAsap();
|
9959
|
-
return
|
10006
|
+
return up.bus.consumeAction(event);
|
9960
10007
|
}
|
9961
10008
|
});
|
9962
10009
|
up.on('up:framework:reset', reset);
|
@@ -9993,7 +10040,7 @@ You can an [`up-tooltip`](/up-tooltip) attribute to any HTML tag to show a toolt
|
|
9993
10040
|
<a href="/decks" up-tooltip="Show all decks">Decks</a>
|
9994
10041
|
|
9995
10042
|
|
9996
|
-
|
10043
|
+
\#\#\# Styling
|
9997
10044
|
|
9998
10045
|
The [default styles](https://github.com/unpoly/unpoly/blob/master/lib/assets/stylesheets/up/tooltip.css.sass)
|
9999
10046
|
show a simple tooltip with white text on a gray background.
|
@@ -10118,8 +10165,16 @@ The tooltip element is appended to the end of `<body>`.
|
|
10118
10165
|
|
10119
10166
|
@function up.tooltip.attach
|
10120
10167
|
@param {Element|jQuery|String} elementOrSelector
|
10168
|
+
@param {String} [options.text]
|
10169
|
+
The text to display in the tooltip.
|
10170
|
+
|
10171
|
+
Any HTML control characters will be escaped.
|
10172
|
+
If you need to use HTML formatting in the tooltip, use `options.html` instead.
|
10121
10173
|
@param {String} [options.html]
|
10122
|
-
The HTML to display in the tooltip.
|
10174
|
+
The HTML to display in the tooltip unescaped.
|
10175
|
+
|
10176
|
+
Make sure to escape any user-provided text before passing it as this option,
|
10177
|
+
or use `options.text` (which automatically escapes).
|
10123
10178
|
@param {String} [options.position='top']
|
10124
10179
|
The position of the tooltip.
|
10125
10180
|
Can be `'top'`, `'right'`, `'bottom'` or `'left'`.
|
@@ -10256,7 +10311,7 @@ The tooltip element is appended to the end of `<body>`.
|
|
10256
10311
|
return closeAsap();
|
10257
10312
|
});
|
10258
10313
|
});
|
10259
|
-
up.on('click
|
10314
|
+
up.on('click up:action:consumed', function(event) {
|
10260
10315
|
return closeAsap();
|
10261
10316
|
});
|
10262
10317
|
up.on('up:framework:reset', reset);
|
@@ -10277,21 +10332,43 @@ The tooltip element is appended to the end of `<body>`.
|
|
10277
10332
|
Navigation bars
|
10278
10333
|
===============
|
10279
10334
|
|
10280
|
-
Unpoly automatically
|
10281
|
-
|
10282
|
-
to the current location (
|
10335
|
+
Unpoly automatically adds CSS classes to links while they are
|
10336
|
+
currently loading ([`.up-active`](/up-active)) or
|
10337
|
+
pointing to the current location ([`.up-current`](/up-current)).
|
10338
|
+
|
10339
|
+
By styling these classes with CSS you can provide instant feedback to user interactions.
|
10340
|
+
This improves the perceived speed of your interface.
|
10341
|
+
|
10342
|
+
\#\#\# Example
|
10343
|
+
|
10344
|
+
Let's say we have an navigation bar with two links, pointing to `/foo` and `/bar` respectively:
|
10345
|
+
|
10346
|
+
<a href="/foo" up-follow>Foo</a>
|
10347
|
+
<a href="/bar" up-follow>Bar</a>
|
10348
|
+
|
10349
|
+
If the current URL is `/foo`, the first link is automatically marked with an [`up-current`](/up-current) class:
|
10350
|
+
|
10351
|
+
<a href="/foo" up-follow class="up-current">Foo</a>
|
10352
|
+
<a href="/bar" up-follow>Bar</a>
|
10353
|
+
|
10354
|
+
When the user clicks on the `/bar` link, the link will receive the [`up-active`](/up-active) class while it is waiting
|
10355
|
+
for the server to respond:
|
10356
|
+
|
10357
|
+
<a href="/foo" up-follow class="up-current">Foo</a>
|
10358
|
+
<a href="/bar" up-follow class="up-active">Bar</a>
|
10359
|
+
|
10360
|
+
Once the response is received the URL will change to `/bar` and the `up-active` class is removed:
|
10361
|
+
|
10362
|
+
<a href="/foo" up-follow>Foo</a>
|
10363
|
+
<a href="/bar" up-follow class="up-current">Bar</a>
|
10283
10364
|
|
10284
|
-
This dramatically improves the perceived speed of your user interface
|
10285
|
-
by providing instant feedback for user interactions.
|
10286
10365
|
|
10287
10366
|
@class up.navigation
|
10288
10367
|
*/
|
10289
10368
|
|
10290
10369
|
(function() {
|
10291
|
-
var slice = [].slice;
|
10292
|
-
|
10293
10370
|
up.navigation = (function($) {
|
10294
|
-
var CLASS_ACTIVE, SELECTOR_SECTION, config, currentClass,
|
10371
|
+
var CLASS_ACTIVE, SELECTOR_SECTION, config, currentClass, findActionableArea, locationChanged, normalizeUrl, reset, sectionUrls, start, stop, u, urlSet;
|
10295
10372
|
u = up.util;
|
10296
10373
|
|
10297
10374
|
/**
|
@@ -10383,23 +10460,70 @@ by providing instant feedback for user interactions.
|
|
10383
10460
|
};
|
10384
10461
|
|
10385
10462
|
/**
|
10386
|
-
@function
|
10463
|
+
@function findActionableArea
|
10387
10464
|
@param {String|Element|jQuery} elementOrSelector
|
10388
|
-
@param {Boolean} options.enlarge
|
10389
|
-
If `true`, tries to find a containing link that has expanded the link's click area.
|
10390
|
-
If we find one, we prefer to mark the larger area as active.
|
10391
10465
|
@internal
|
10392
10466
|
*/
|
10393
|
-
|
10467
|
+
findActionableArea = function(elementOrSelector) {
|
10394
10468
|
var $area;
|
10395
10469
|
$area = $(elementOrSelector);
|
10396
|
-
|
10397
|
-
|
10398
|
-
}
|
10399
|
-
|
10400
|
-
|
10401
|
-
|
10402
|
-
|
10470
|
+
if ($area.is(SELECTOR_SECTION)) {
|
10471
|
+
$area = u.presence($area.parent(SELECTOR_SECTION)) || $area;
|
10472
|
+
}
|
10473
|
+
return $area;
|
10474
|
+
};
|
10475
|
+
|
10476
|
+
/**
|
10477
|
+
Marks the given element as currently loading, by assigning the CSS class [`up-active`](/up-active).
|
10478
|
+
|
10479
|
+
This happens automatically when following links or submitting forms through the Unpoly API.
|
10480
|
+
Use this function if you make custom network calls from your own Javascript code.
|
10481
|
+
|
10482
|
+
If the given element is a link within an [expanded click area](/up-expand),
|
10483
|
+
the class will be assigned to the expanded area.
|
10484
|
+
|
10485
|
+
\#\#\# Example
|
10486
|
+
|
10487
|
+
var $button = $('button');
|
10488
|
+
$button.on('click', function() {
|
10489
|
+
up.navigation.start($button);
|
10490
|
+
up.ajax(...).always(function() {
|
10491
|
+
up.navigation.stop($button);
|
10492
|
+
});
|
10493
|
+
});
|
10494
|
+
|
10495
|
+
Or shorter:
|
10496
|
+
|
10497
|
+
var $button = $('button');
|
10498
|
+
$button.on('click', function() {
|
10499
|
+
up.navigation.start($button, function() {
|
10500
|
+
up.ajax(...);
|
10501
|
+
});
|
10502
|
+
});
|
10503
|
+
|
10504
|
+
@method up.navigation.start
|
10505
|
+
@param {Element|jQuery|String} elementOrSelector
|
10506
|
+
The element to mark as active
|
10507
|
+
@param {Function} [action]
|
10508
|
+
An optional function to run while the element is marked as loading.
|
10509
|
+
The function must return a promise.
|
10510
|
+
Once the promise resolves, the element will be [marked as no longer loading](/up.navigation.stop).
|
10511
|
+
@internal
|
10512
|
+
*/
|
10513
|
+
start = function(elementOrSelector, action) {
|
10514
|
+
var $element, promise;
|
10515
|
+
$element = findActionableArea(elementOrSelector);
|
10516
|
+
$element.addClass(CLASS_ACTIVE);
|
10517
|
+
if (action) {
|
10518
|
+
promise = action();
|
10519
|
+
if (u.isPromise(promise)) {
|
10520
|
+
promise.always(function() {
|
10521
|
+
return stop($element);
|
10522
|
+
});
|
10523
|
+
} else {
|
10524
|
+
up.warn('Expected block to return a promise, but got %o', promise);
|
10525
|
+
}
|
10526
|
+
return promise;
|
10403
10527
|
}
|
10404
10528
|
};
|
10405
10529
|
|
@@ -10411,7 +10535,7 @@ by providing instant feedback for user interactions.
|
|
10411
10535
|
The `up-active` class will be removed as soon as another
|
10412
10536
|
page fragment is added or updated through Unpoly.
|
10413
10537
|
|
10414
|
-
|
10538
|
+
\#\#\# Example
|
10415
10539
|
|
10416
10540
|
We have a link:
|
10417
10541
|
|
@@ -10430,33 +10554,27 @@ by providing instant feedback for user interactions.
|
|
10430
10554
|
@selector .up-active
|
10431
10555
|
@stable
|
10432
10556
|
*/
|
10433
|
-
|
10434
|
-
|
10435
|
-
|
10436
|
-
|
10437
|
-
|
10438
|
-
|
10557
|
+
|
10558
|
+
/**
|
10559
|
+
Marks the given element as no longer loading, by removing the CSS class [`up-active`](/up-active).
|
10560
|
+
|
10561
|
+
This happens automatically when network requests initiated by the Unpoly API have completed.
|
10562
|
+
Use this function if you make custom network calls from your own Javascript code.
|
10563
|
+
|
10564
|
+
@function up.navigation.stop
|
10565
|
+
@param {jQuery} event.$element
|
10566
|
+
The link or form that has finished loading.
|
10567
|
+
@internal
|
10568
|
+
*/
|
10569
|
+
stop = function(elementOrSelector) {
|
10439
10570
|
var $element;
|
10440
|
-
$element =
|
10571
|
+
$element = findActionableArea(elementOrSelector);
|
10572
|
+
up.emit('up:navigated', {
|
10573
|
+
$element: $element,
|
10574
|
+
message: false
|
10575
|
+
});
|
10441
10576
|
return $element.removeClass(CLASS_ACTIVE);
|
10442
10577
|
};
|
10443
|
-
withActiveMark = function() {
|
10444
|
-
var $element, args, block, elementOrSelector, options, promise;
|
10445
|
-
elementOrSelector = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
10446
|
-
block = args.pop();
|
10447
|
-
options = u.options(args.pop());
|
10448
|
-
$element = $(elementOrSelector);
|
10449
|
-
markActive($element, options);
|
10450
|
-
promise = block();
|
10451
|
-
if (u.isPromise(promise)) {
|
10452
|
-
promise.always(function() {
|
10453
|
-
return unmarkActive($element, options);
|
10454
|
-
});
|
10455
|
-
} else {
|
10456
|
-
up.warn('Expected block to return a promise, but got %o', promise);
|
10457
|
-
}
|
10458
|
-
return promise;
|
10459
|
-
};
|
10460
10578
|
|
10461
10579
|
/**
|
10462
10580
|
Links that point to the current location are assigned
|
@@ -10476,7 +10594,7 @@ by providing instant feedback for user interactions.
|
|
10476
10594
|
<a href="/bar">Bar</a>
|
10477
10595
|
</nav>
|
10478
10596
|
|
10479
|
-
|
10597
|
+
\#\#\# What's considered to be "current"?
|
10480
10598
|
|
10481
10599
|
The current location is considered to be either:
|
10482
10600
|
|
@@ -10516,9 +10634,8 @@ by providing instant feedback for user interactions.
|
|
10516
10634
|
defaults: function() {
|
10517
10635
|
return up.fail('up.navigation.defaults(...) no longer exists. Set values on he up.navigation.config property instead.');
|
10518
10636
|
},
|
10519
|
-
|
10520
|
-
|
10521
|
-
withActiveMark: withActiveMark
|
10637
|
+
start: start,
|
10638
|
+
stop: stop
|
10522
10639
|
};
|
10523
10640
|
})(jQuery);
|
10524
10641
|
|