unpoly-rails 0.28.1 → 0.29.0
Sign up to get free protection for your applications and to get access to all the features.
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
|
|