unpoly-rails 0.24.1 → 0.25.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 +31 -0
- data/README_RAILS.md +8 -1
- data/dist/unpoly.css +22 -10
- data/dist/unpoly.js +406 -196
- data/dist/unpoly.min.css +1 -1
- data/dist/unpoly.min.js +3 -3
- data/lib/assets/javascripts/unpoly/flow.js.coffee +36 -19
- data/lib/assets/javascripts/unpoly/form.js.coffee +1 -2
- data/lib/assets/javascripts/unpoly/link.js.coffee +2 -2
- data/lib/assets/javascripts/unpoly/modal.js.coffee +174 -81
- data/lib/assets/javascripts/unpoly/navigation.js.coffee +3 -1
- data/lib/assets/javascripts/unpoly/popup.js.coffee +62 -37
- data/lib/assets/javascripts/unpoly/proxy.js.coffee +1 -0
- data/lib/assets/javascripts/unpoly/syntax.js.coffee +12 -4
- data/lib/assets/javascripts/unpoly/util.js.coffee +55 -13
- data/lib/assets/stylesheets/unpoly/modal.css.sass +28 -12
- data/lib/unpoly/rails/inspector.rb +26 -0
- data/lib/unpoly/rails/version.rb +1 -1
- data/spec_app/Gemfile.lock +1 -1
- data/spec_app/app/controllers/binding_test_controller.rb +6 -0
- data/spec_app/spec/controllers/binding_test_controller_spec.rb +82 -11
- data/spec_app/spec/javascripts/up/flow_spec.js.coffee +21 -7
- data/spec_app/spec/javascripts/up/form_spec.js.coffee +15 -0
- data/spec_app/spec/javascripts/up/link_spec.js.coffee +11 -10
- data/spec_app/spec/javascripts/up/modal_spec.js.coffee +232 -30
- data/spec_app/spec/javascripts/up/motion_spec.js.coffee +33 -27
- data/spec_app/spec/javascripts/up/popup_spec.js.coffee +72 -0
- data/spec_app/spec/javascripts/up/syntax_spec.js.coffee +51 -13
- metadata +2 -2
data/dist/unpoly.js
CHANGED
@@ -29,7 +29,7 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
29
29
|
@function up.util.noop
|
30
30
|
@experimental
|
31
31
|
*/
|
32
|
-
var $createElementFromSelector, $createPlaceholder, ANIMATION_DEFERRED_KEY, all, any, appendRequestData, cache, castedAttr, clientSize, compact, config, contains, copy, copyAttributes, createElement, createElementFromHtml, cssAnimate, detect, each, error, escapePressed, except, extend, extractOptions, findWithSelf, finishCssAnimate, fixedToAbsolute, forceCompositing, forceRepaint, intersect, isArray, isBlank, isDeferred, isDefined, isDetached, isElement, 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, option, options, parseUrl, pluckData, pluckKey, presence, presentAttr, reject, remove, requestDataAsArray, requestDataAsQuery, requestDataFromForm, resolvableWhen, resolvedDeferred, resolvedPromise, scrollbarWidth, select, selectorForElement, setMissingAttrs, setTimer, temporaryCss, times, titleFromXhr, toArray, trim, unJQuery, uniq, unresolvableDeferred, unresolvablePromise, unwrapElement;
|
32
|
+
var $createElementFromSelector, $createPlaceholder, ANIMATION_DEFERRED_KEY, all, any, appendRequestData, cache, castedAttr, clientSize, compact, config, contains, copy, copyAttributes, createElement, createElementFromHtml, cssAnimate, detect, documentHasVerticalScrollbar, each, error, escapePressed, except, extend, extractOptions, findWithSelf, finishCssAnimate, fixedToAbsolute, forceCompositing, forceRepaint, intersect, isArray, isBlank, isDeferred, isDefined, isDetached, isElement, 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, reject, remove, requestDataAsArray, requestDataAsQuery, requestDataFromForm, resolvableWhen, resolvedDeferred, resolvedPromise, scrollbarWidth, select, selectorForElement, setMissingAttrs, setTimer, temporaryCss, times, titleFromXhr, toArray, trim, unJQuery, uniq, unresolvableDeferred, unresolvablePromise, unwrapElement;
|
33
33
|
noop = $.noop;
|
34
34
|
|
35
35
|
/**
|
@@ -989,6 +989,23 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
989
989
|
return width;
|
990
990
|
});
|
991
991
|
|
992
|
+
/**
|
993
|
+
Returns whether the given element is currently showing a vertical scrollbar.
|
994
|
+
|
995
|
+
@function up.util.documentHasVerticalScrollbar
|
996
|
+
@internal
|
997
|
+
*/
|
998
|
+
documentHasVerticalScrollbar = function() {
|
999
|
+
var $body, body, bodyOverflow, forcedHidden, forcedScroll, html;
|
1000
|
+
body = document.body;
|
1001
|
+
$body = $(body);
|
1002
|
+
html = document.documentElement;
|
1003
|
+
bodyOverflow = $body.css('overflow-y');
|
1004
|
+
forcedScroll = bodyOverflow === 'scroll';
|
1005
|
+
forcedHidden = bodyOverflow === 'hidden';
|
1006
|
+
return forcedScroll || (!forcedHidden && html.scrollHeight > html.clientHeight);
|
1007
|
+
};
|
1008
|
+
|
992
1009
|
/**
|
993
1010
|
Modifies the given function so it only runs once.
|
994
1011
|
Subsequent calls will return the previous return value.
|
@@ -1100,7 +1117,7 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
1100
1117
|
@internal
|
1101
1118
|
*/
|
1102
1119
|
cssAnimate = function(elementOrSelector, lastFrame, opts) {
|
1103
|
-
var $element,
|
1120
|
+
var $element, deferred, oldTransition, onTransitionEnd, transition, transitionFinished, transitionProperties, withoutCompositing;
|
1104
1121
|
$element = $(elementOrSelector);
|
1105
1122
|
opts = options(opts, {
|
1106
1123
|
duration: 300,
|
@@ -1108,14 +1125,29 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
1108
1125
|
easing: 'ease'
|
1109
1126
|
});
|
1110
1127
|
deferred = $.Deferred();
|
1128
|
+
transitionProperties = Object.keys(lastFrame);
|
1111
1129
|
transition = {
|
1112
|
-
'transition-property':
|
1130
|
+
'transition-property': transitionProperties.join(', '),
|
1113
1131
|
'transition-duration': opts.duration + "ms",
|
1114
1132
|
'transition-delay': opts.delay + "ms",
|
1115
1133
|
'transition-timing-function': opts.easing
|
1116
1134
|
};
|
1117
1135
|
oldTransition = $element.css(Object.keys(transition));
|
1118
1136
|
$element.addClass('up-animating');
|
1137
|
+
transitionFinished = function() {
|
1138
|
+
$element.removeClass('up-animating');
|
1139
|
+
return $element.off('transitionend', onTransitionEnd);
|
1140
|
+
};
|
1141
|
+
onTransitionEnd = function(event) {
|
1142
|
+
var completedProperty;
|
1143
|
+
completedProperty = event.originalEvent.propertyName;
|
1144
|
+
if (contains(transitionProperties, completedProperty)) {
|
1145
|
+
deferred.resolve();
|
1146
|
+
return transitionFinished();
|
1147
|
+
}
|
1148
|
+
};
|
1149
|
+
$element.on('transitionend', onTransitionEnd);
|
1150
|
+
deferred.then(transitionFinished);
|
1119
1151
|
withoutCompositing = forceCompositing($element);
|
1120
1152
|
$element.css(transition);
|
1121
1153
|
$element.css(lastFrame);
|
@@ -1133,16 +1165,6 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
1133
1165
|
return $element.css(oldTransition);
|
1134
1166
|
}
|
1135
1167
|
});
|
1136
|
-
animationEnd = opts.duration + opts.delay;
|
1137
|
-
endTimeout = setTimer(animationEnd, function() {
|
1138
|
-
$element.removeClass('up-animating');
|
1139
|
-
if (!isDetached($element)) {
|
1140
|
-
return deferred.resolve();
|
1141
|
-
}
|
1142
|
-
});
|
1143
|
-
deferred.then(function() {
|
1144
|
-
return clearTimeout(endTimeout);
|
1145
|
-
});
|
1146
1168
|
return deferred;
|
1147
1169
|
};
|
1148
1170
|
ANIMATION_DEFERRED_KEY = 'up-animation-deferred';
|
@@ -1941,6 +1963,15 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
1941
1963
|
return {};
|
1942
1964
|
}
|
1943
1965
|
};
|
1966
|
+
opacity = function(element) {
|
1967
|
+
var rawOpacity;
|
1968
|
+
rawOpacity = $(element).css('opacity');
|
1969
|
+
if (isGiven(rawOpacity)) {
|
1970
|
+
return parseFloat(rawOpacity);
|
1971
|
+
} else {
|
1972
|
+
return void 0;
|
1973
|
+
}
|
1974
|
+
};
|
1944
1975
|
|
1945
1976
|
/**
|
1946
1977
|
Returns whether the given element has been detached from the DOM
|
@@ -2040,6 +2071,7 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
2040
2071
|
remove: remove,
|
2041
2072
|
memoize: memoize,
|
2042
2073
|
scrollbarWidth: scrollbarWidth,
|
2074
|
+
documentHasVerticalScrollbar: documentHasVerticalScrollbar,
|
2043
2075
|
config: config,
|
2044
2076
|
cache: cache,
|
2045
2077
|
unwrapElement: unwrapElement,
|
@@ -2049,7 +2081,8 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
2049
2081
|
pluckKey: pluckKey,
|
2050
2082
|
extractOptions: extractOptions,
|
2051
2083
|
isDetached: isDetached,
|
2052
|
-
noop: noop
|
2084
|
+
noop: noop,
|
2085
|
+
opacity: opacity
|
2053
2086
|
};
|
2054
2087
|
})($);
|
2055
2088
|
|
@@ -3203,6 +3236,11 @@ later.
|
|
3203
3236
|
options = u.options(args[0], {
|
3204
3237
|
priority: 0
|
3205
3238
|
});
|
3239
|
+
if (options.priority === 'first') {
|
3240
|
+
options.priority = Number.POSITIVE_INFINITY;
|
3241
|
+
} else if (options.priority === 'last') {
|
3242
|
+
options.priority = Number.NEGATIVE_INFINITY;
|
3243
|
+
}
|
3206
3244
|
return {
|
3207
3245
|
selector: selector,
|
3208
3246
|
callback: callback,
|
@@ -3219,7 +3257,7 @@ later.
|
|
3219
3257
|
}
|
3220
3258
|
newCompiler = buildCompiler.apply(null, args);
|
3221
3259
|
index = 0;
|
3222
|
-
while ((oldCompiler = queue[index]) && (oldCompiler.priority
|
3260
|
+
while ((oldCompiler = queue[index]) && (oldCompiler.priority >= newCompiler.priority)) {
|
3223
3261
|
index += 1;
|
3224
3262
|
}
|
3225
3263
|
return queue.splice(index, 0, newCompiler);
|
@@ -3304,6 +3342,7 @@ later.
|
|
3304
3342
|
var $element, destroyer;
|
3305
3343
|
$element = $(this);
|
3306
3344
|
destroyer = $element.data(DESTROYER_KEY);
|
3345
|
+
$element.removeClass(DESTROYABLE_CLASS);
|
3307
3346
|
return destroyer();
|
3308
3347
|
});
|
3309
3348
|
};
|
@@ -3394,13 +3433,12 @@ later.
|
|
3394
3433
|
@internal
|
3395
3434
|
*/
|
3396
3435
|
snapshot = function() {
|
3397
|
-
var
|
3398
|
-
|
3399
|
-
|
3400
|
-
|
3401
|
-
|
3402
|
-
|
3403
|
-
return results;
|
3436
|
+
var setDefault;
|
3437
|
+
setDefault = function(compiler) {
|
3438
|
+
return compiler.isDefault = true;
|
3439
|
+
};
|
3440
|
+
u.each(compilers, setDefault);
|
3441
|
+
return u.each(macros, setDefault);
|
3404
3442
|
};
|
3405
3443
|
|
3406
3444
|
/**
|
@@ -3410,9 +3448,12 @@ later.
|
|
3410
3448
|
@internal
|
3411
3449
|
*/
|
3412
3450
|
reset = function() {
|
3413
|
-
|
3451
|
+
var isDefault;
|
3452
|
+
isDefault = function(compiler) {
|
3414
3453
|
return compiler.isDefault;
|
3415
|
-
}
|
3454
|
+
};
|
3455
|
+
compilers = u.select(compilers, isDefault);
|
3456
|
+
return macros = u.select(macros, isDefault);
|
3416
3457
|
};
|
3417
3458
|
up.on('up:framework:boot', snapshot);
|
3418
3459
|
up.on('up:framework:reset', reset);
|
@@ -4495,7 +4536,7 @@ are based on this module.
|
|
4495
4536
|
@stable
|
4496
4537
|
*/
|
4497
4538
|
replace = function(selectorOrElement, url, options) {
|
4498
|
-
var failTarget, promise, request, target;
|
4539
|
+
var failTarget, onFailure, onSuccess, promise, request, target;
|
4499
4540
|
up.puts("Replacing %s from %s (%o)", selectorOrElement, url, options);
|
4500
4541
|
options = u.options(options);
|
4501
4542
|
target = resolveSelector(selectorOrElement, options.origin);
|
@@ -4518,12 +4559,13 @@ are based on this module.
|
|
4518
4559
|
headers: options.headers
|
4519
4560
|
};
|
4520
4561
|
promise = up.ajax(request);
|
4521
|
-
|
4562
|
+
onSuccess = function(html, textStatus, xhr) {
|
4522
4563
|
return processResponse(true, target, url, request, xhr, options);
|
4523
|
-
}
|
4524
|
-
|
4564
|
+
};
|
4565
|
+
onFailure = function(xhr, textStatus, errorThrown) {
|
4525
4566
|
return processResponse(false, failTarget, url, request, xhr, options);
|
4526
|
-
}
|
4567
|
+
};
|
4568
|
+
promise = promise.then(onSuccess, onFailure);
|
4527
4569
|
return promise;
|
4528
4570
|
};
|
4529
4571
|
|
@@ -4631,7 +4673,7 @@ are based on this module.
|
|
4631
4673
|
*/
|
4632
4674
|
extract = function(selectorOrElement, html, options) {
|
4633
4675
|
return up.log.group('Extracting %s from %d bytes of HTML', selectorOrElement, html != null ? html.length : void 0, function() {
|
4634
|
-
var
|
4676
|
+
var promise, response, selector;
|
4635
4677
|
options = u.options(options, {
|
4636
4678
|
historyMethod: 'push',
|
4637
4679
|
requireMatch: true,
|
@@ -4643,28 +4685,35 @@ are based on this module.
|
|
4643
4685
|
if (options.saveScroll !== false) {
|
4644
4686
|
up.layout.saveScroll();
|
4645
4687
|
}
|
4646
|
-
|
4647
|
-
|
4648
|
-
|
4649
|
-
deferreds = [];
|
4650
|
-
updateHistory(options);
|
4651
|
-
ref = parseImplantSteps(selector, options);
|
4652
|
-
for (j = 0, len = ref.length; j < len; j++) {
|
4653
|
-
step = ref[j];
|
4654
|
-
up.log.group('Updating %s', step.selector, function() {
|
4655
|
-
var $new, $old, deferred, ref1;
|
4656
|
-
$old = findOldFragment(step.selector, options);
|
4657
|
-
$new = (ref1 = response.find(step.selector)) != null ? ref1.first() : void 0;
|
4658
|
-
if ($old && $new) {
|
4659
|
-
deferred = swapElements($old, $new, step.pseudoClass, step.transition, options);
|
4660
|
-
return deferreds.push(deferred);
|
4661
|
-
}
|
4662
|
-
});
|
4688
|
+
promise = u.resolvedPromise();
|
4689
|
+
if (options.beforeSwap) {
|
4690
|
+
promise = promise.then(options.beforeSwap);
|
4663
4691
|
}
|
4664
|
-
|
4665
|
-
options
|
4692
|
+
promise = promise.then(function() {
|
4693
|
+
return updateHistory(options);
|
4694
|
+
});
|
4695
|
+
promise = promise.then(function() {
|
4696
|
+
var j, len, ref, step, swapPromises;
|
4697
|
+
swapPromises = [];
|
4698
|
+
ref = parseImplantSteps(selector, options);
|
4699
|
+
for (j = 0, len = ref.length; j < len; j++) {
|
4700
|
+
step = ref[j];
|
4701
|
+
up.log.group('Updating %s', step.selector, function() {
|
4702
|
+
var $new, $old, ref1, swapPromise;
|
4703
|
+
$old = findOldFragment(step.selector, options);
|
4704
|
+
$new = (ref1 = response.find(step.selector)) != null ? ref1.first() : void 0;
|
4705
|
+
if ($old && $new) {
|
4706
|
+
swapPromise = swapElements($old, $new, step.pseudoClass, step.transition, options);
|
4707
|
+
return swapPromises.push(swapPromise);
|
4708
|
+
}
|
4709
|
+
});
|
4710
|
+
}
|
4711
|
+
return $.when.apply($, swapPromises);
|
4712
|
+
});
|
4713
|
+
if (options.afterSwap) {
|
4714
|
+
promise = promise.then(options.afterSwap);
|
4666
4715
|
}
|
4667
|
-
return
|
4716
|
+
return promise;
|
4668
4717
|
});
|
4669
4718
|
};
|
4670
4719
|
findOldFragment = function(selector, options) {
|
@@ -4736,7 +4785,12 @@ are based on this module.
|
|
4736
4785
|
} else {
|
4737
4786
|
replacement = function() {
|
4738
4787
|
options.keepPlans = transferKeepableElements($old, $new, options);
|
4739
|
-
$
|
4788
|
+
if ($old.is('body')) {
|
4789
|
+
up.syntax.clean($old);
|
4790
|
+
$old.replaceWith($new);
|
4791
|
+
} else {
|
4792
|
+
$new.insertBefore($old);
|
4793
|
+
}
|
4740
4794
|
if (options.source !== false) {
|
4741
4795
|
setSource($new, options.source);
|
4742
4796
|
}
|
@@ -6344,7 +6398,7 @@ the user performs the click.
|
|
6344
6398
|
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|
6345
6399
|
return (ref = entry.deferred).resolve.apply(ref, args);
|
6346
6400
|
});
|
6347
|
-
|
6401
|
+
promise.fail(function() {
|
6348
6402
|
var args, ref;
|
6349
6403
|
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|
6350
6404
|
return (ref = entry.deferred).reject.apply(ref, args);
|
@@ -6952,7 +7006,9 @@ Read on
|
|
6952
7006
|
@selector [up-dash]
|
6953
7007
|
@stable
|
6954
7008
|
*/
|
6955
|
-
up.macro('[up-dash]',
|
7009
|
+
up.macro('[up-dash]', {
|
7010
|
+
priority: 'last'
|
7011
|
+
}, function($element) {
|
6956
7012
|
var newAttrs, target;
|
6957
7013
|
target = u.castedAttr($element, 'up-dash');
|
6958
7014
|
$element.removeAttr('up-dash');
|
@@ -7005,7 +7061,9 @@ Read on
|
|
7005
7061
|
If omitted, the first contained link will be expanded.
|
7006
7062
|
@stable
|
7007
7063
|
*/
|
7008
|
-
up.macro('[up-expand]',
|
7064
|
+
up.macro('[up-expand]', {
|
7065
|
+
priority: 'last'
|
7066
|
+
}, function($area) {
|
7009
7067
|
var $childLinks, attribute, i, len, link, name, newAttrs, ref, selector, upAttributePattern;
|
7010
7068
|
$childLinks = $area.find('a, [up-href]');
|
7011
7069
|
if (selector = $area.attr('up-expand')) {
|
@@ -7376,9 +7434,8 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
7376
7434
|
return observe(selectorOrElement, options, function(value, $field) {
|
7377
7435
|
var $form;
|
7378
7436
|
$form = $field.closest('form');
|
7379
|
-
$field
|
7380
|
-
|
7381
|
-
return $field.removeClass('up-active');
|
7437
|
+
return up.navigation.withActiveMark($field, function() {
|
7438
|
+
return submit($form);
|
7382
7439
|
});
|
7383
7440
|
});
|
7384
7441
|
};
|
@@ -7963,7 +8020,7 @@ Pop-up overlays
|
|
7963
8020
|
Instead of [linking to a page fragment](/up.link), you can choose
|
7964
8021
|
to show a fragment in a popup overlay that rolls down from an anchoring element.
|
7965
8022
|
|
7966
|
-
To open a popup, add an [`up-popup` attribute](/
|
8023
|
+
To open a popup, add an [`up-popup` attribute](/up-popup) to a link,
|
7967
8024
|
or call the Javascript function [`up.popup.attach`](/up.popup.attach).
|
7968
8025
|
|
7969
8026
|
For modal dialogs see [up.modal](/up.modal) instead.
|
@@ -7989,7 +8046,7 @@ By default the popup uses the following DOM structure:
|
|
7989
8046
|
The popup closes when the user clicks anywhere outside the popup area.
|
7990
8047
|
|
7991
8048
|
By default the popup also closes
|
7992
|
-
*
|
8049
|
+
*when a link within the popup changes a fragment behind the popup*.
|
7993
8050
|
This is useful to have the popup interact with the page that
|
7994
8051
|
opened it, e.g. by updating parts of a larger form or by signing in a user
|
7995
8052
|
and revealing additional information.
|
@@ -8032,21 +8089,36 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
8032
8089
|
Sets default options for future popups.
|
8033
8090
|
|
8034
8091
|
@property up.popup.config
|
8035
|
-
@param {String} [config.openAnimation='fade-in']
|
8036
|
-
The animation used to open a popup.
|
8037
|
-
@param {String} [config.closeAnimation='fade-out']
|
8038
|
-
The animation used to close a popup.
|
8039
8092
|
@param {String} [config.position='bottom-right']
|
8040
8093
|
Defines where the popup is attached to the opening element.
|
8041
8094
|
|
8042
8095
|
Valid values are `bottom-right`, `bottom-left`, `top-right` and `top-left`.
|
8043
8096
|
@param {String} [config.history=false]
|
8044
8097
|
Whether opening a popup will add a browser history entry.
|
8098
|
+
@param {String} [config.openAnimation='fade-in']
|
8099
|
+
The animation used to open a popup.
|
8100
|
+
@param {String} [config.closeAnimation='fade-out']
|
8101
|
+
The animation used to close a popup.
|
8102
|
+
@param {String} [config.openDuration]
|
8103
|
+
The duration of the open animation (in milliseconds).
|
8104
|
+
@param {String} [config.closeDuration]
|
8105
|
+
The duration of the close animation (in milliseconds).
|
8106
|
+
@param {String} [config.openEasing]
|
8107
|
+
The timing function controlling the acceleration of the opening animation.
|
8108
|
+
@param {String} [config.closeEasing]
|
8109
|
+
The timing function controlling the acceleration of the closing animation.
|
8110
|
+
@param {Boolean} [options.sticky=false]
|
8111
|
+
If set to `true`, the popup remains
|
8112
|
+
open even it changes the page in the background.
|
8045
8113
|
@stable
|
8046
8114
|
*/
|
8047
8115
|
config = u.config({
|
8048
8116
|
openAnimation: 'fade-in',
|
8049
8117
|
closeAnimation: 'fade-out',
|
8118
|
+
openDuration: null,
|
8119
|
+
closeDuration: null,
|
8120
|
+
openEasing: null,
|
8121
|
+
closeEasing: null,
|
8050
8122
|
position: 'bottom-right',
|
8051
8123
|
history: false
|
8052
8124
|
});
|
@@ -8133,16 +8205,26 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
8133
8205
|
return $popup.removeAttr('up-covered-title');
|
8134
8206
|
};
|
8135
8207
|
createFrame = function(target, options) {
|
8136
|
-
var
|
8137
|
-
|
8138
|
-
if (
|
8139
|
-
|
8208
|
+
var promise;
|
8209
|
+
promise = u.resolvedPromise();
|
8210
|
+
if (isOpen()) {
|
8211
|
+
promise = promise.then(function() {
|
8212
|
+
return close();
|
8213
|
+
});
|
8140
8214
|
}
|
8141
|
-
|
8142
|
-
|
8143
|
-
|
8144
|
-
|
8145
|
-
|
8215
|
+
promise = promise.then(function() {
|
8216
|
+
var $popup;
|
8217
|
+
$popup = u.$createElementFromSelector('.up-popup');
|
8218
|
+
if (options.sticky) {
|
8219
|
+
$popup.attr('up-sticky', '');
|
8220
|
+
}
|
8221
|
+
$popup.attr('up-covered-url', up.browser.url());
|
8222
|
+
$popup.attr('up-covered-title', document.title);
|
8223
|
+
u.$createPlaceholder(target, $popup);
|
8224
|
+
$popup.appendTo(document.body);
|
8225
|
+
return $popup;
|
8226
|
+
});
|
8227
|
+
return promise;
|
8146
8228
|
};
|
8147
8229
|
|
8148
8230
|
/**
|
@@ -8163,6 +8245,8 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
8163
8245
|
@function up.popup.attach
|
8164
8246
|
@param {Element|jQuery|String} elementOrSelector
|
8165
8247
|
@param {String} [options.url]
|
8248
|
+
@param {String} [options.target]
|
8249
|
+
A CSS selector that will be extracted from the response and placed into the popup.
|
8166
8250
|
@param {String} [options.position='bottom-right']
|
8167
8251
|
Defines where the popup is attached to the opening element.
|
8168
8252
|
|
@@ -8188,44 +8272,45 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
8188
8272
|
@stable
|
8189
8273
|
*/
|
8190
8274
|
attach = function(linkOrSelector, options) {
|
8191
|
-
var $link, animateOptions, target, url;
|
8275
|
+
var $link, animateOptions, html, target, url;
|
8192
8276
|
$link = $(linkOrSelector);
|
8193
8277
|
$link.length || u.error('Cannot attach popup to non-existing element %o', linkOrSelector);
|
8194
8278
|
options = u.options(options);
|
8195
|
-
url = u.option(options
|
8196
|
-
|
8279
|
+
url = u.option(u.pluckKey(options, 'url'), $link.attr('up-href'), $link.attr('href'));
|
8280
|
+
html = u.option(u.pluckKey(options, 'html'));
|
8281
|
+
target = u.option(u.pluckKey(options, 'target'), $link.attr('up-popup'), 'body');
|
8197
8282
|
options.position = u.option(options.position, $link.attr('up-position'), config.position);
|
8198
8283
|
options.animation = u.option(options.animation, $link.attr('up-animation'), config.openAnimation);
|
8199
|
-
options.sticky = u.option(options.sticky, u.castedAttr($link, 'up-sticky'));
|
8284
|
+
options.sticky = u.option(options.sticky, u.castedAttr($link, 'up-sticky'), config.sticky);
|
8200
8285
|
options.history = up.browser.canPushState() ? u.option(options.history, u.castedAttr($link, 'up-history'), config.history) : false;
|
8201
8286
|
options.confirm = u.option(options.confirm, $link.attr('up-confirm'));
|
8202
|
-
animateOptions = up.motion.animateOptions(options, $link
|
8287
|
+
animateOptions = up.motion.animateOptions(options, $link, {
|
8288
|
+
duration: config.openDuration,
|
8289
|
+
easing: config.openEasing
|
8290
|
+
});
|
8203
8291
|
return up.browser.confirm(options).then(function() {
|
8204
|
-
var
|
8292
|
+
var extractOptions, promise;
|
8205
8293
|
if (up.bus.nobodyPrevents('up:popup:open', {
|
8206
8294
|
url: url,
|
8207
8295
|
message: 'Opening popup'
|
8208
8296
|
})) {
|
8209
|
-
wasOpen = isOpen();
|
8210
|
-
if (wasOpen) {
|
8211
|
-
close({
|
8212
|
-
animation: false
|
8213
|
-
});
|
8214
|
-
}
|
8215
8297
|
options.beforeSwap = function() {
|
8216
8298
|
return createFrame(target, options);
|
8217
8299
|
};
|
8218
|
-
|
8300
|
+
extractOptions = u.merge(options, {
|
8219
8301
|
animation: false
|
8220
|
-
})
|
8302
|
+
});
|
8303
|
+
if (html) {
|
8304
|
+
promise = up.extract(target, html, extractOptions);
|
8305
|
+
} else {
|
8306
|
+
promise = up.replace(target, url, extractOptions);
|
8307
|
+
}
|
8221
8308
|
promise = promise.then(function() {
|
8222
8309
|
return setPosition($link, options.position);
|
8223
8310
|
});
|
8224
|
-
|
8225
|
-
|
8226
|
-
|
8227
|
-
});
|
8228
|
-
}
|
8311
|
+
promise = promise.then(function() {
|
8312
|
+
return up.animate($('.up-popup'), options.animation, animateOptions);
|
8313
|
+
});
|
8229
8314
|
promise = promise.then(function() {
|
8230
8315
|
return up.emit('up:popup:opened', {
|
8231
8316
|
message: 'Popup opened'
|
@@ -8233,7 +8318,7 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
8233
8318
|
});
|
8234
8319
|
return promise;
|
8235
8320
|
} else {
|
8236
|
-
return u.
|
8321
|
+
return u.unresolvablePromise();
|
8237
8322
|
}
|
8238
8323
|
});
|
8239
8324
|
};
|
@@ -8264,13 +8349,13 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
8264
8349
|
@function up.popup.close
|
8265
8350
|
@param {Object} options
|
8266
8351
|
See options for [`up.animate`](/up.animate).
|
8267
|
-
@return {
|
8352
|
+
@return {Promise}
|
8268
8353
|
A promise that will be resolved once the modal's close
|
8269
8354
|
animation has finished.
|
8270
8355
|
@stable
|
8271
8356
|
*/
|
8272
8357
|
close = function(options) {
|
8273
|
-
var $popup,
|
8358
|
+
var $popup, animateOptions, promise;
|
8274
8359
|
$popup = $('.up-popup');
|
8275
8360
|
if ($popup.length) {
|
8276
8361
|
if (up.bus.nobodyPrevents('up:popup:close', {
|
@@ -8281,19 +8366,24 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
8281
8366
|
url: $popup.attr('up-covered-url'),
|
8282
8367
|
title: $popup.attr('up-covered-title')
|
8283
8368
|
});
|
8369
|
+
animateOptions = up.motion.animateOptions(options, {
|
8370
|
+
duration: config.closeDuration,
|
8371
|
+
easing: config.closeEasing
|
8372
|
+
});
|
8373
|
+
u.extend(options, animateOptions);
|
8284
8374
|
currentUrl = void 0;
|
8285
|
-
|
8286
|
-
|
8375
|
+
promise = up.destroy($popup, options);
|
8376
|
+
promise = promise.then(function() {
|
8287
8377
|
return up.emit('up:popup:closed', {
|
8288
8378
|
message: 'Popup closed'
|
8289
8379
|
});
|
8290
8380
|
});
|
8291
|
-
return
|
8381
|
+
return promise;
|
8292
8382
|
} else {
|
8293
|
-
return u.
|
8383
|
+
return u.unresolvablePromise();
|
8294
8384
|
}
|
8295
8385
|
} else {
|
8296
|
-
return u.
|
8386
|
+
return u.resolvedPromise();
|
8297
8387
|
}
|
8298
8388
|
};
|
8299
8389
|
|
@@ -8346,7 +8436,7 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
8346
8436
|
<a href="/decks" up-popup=".deck_list">Switch deck</a>
|
8347
8437
|
<a href="/settings" up-popup=".options" up-sticky>Settings</a>
|
8348
8438
|
|
8349
|
-
@selector
|
8439
|
+
@selector [up-popup]
|
8350
8440
|
@param [up-position]
|
8351
8441
|
Defines where the popup is attached to the opening element.
|
8352
8442
|
|
@@ -8441,7 +8531,7 @@ Instead of [linking to a page fragment](/up.link), you can choose
|
|
8441
8531
|
to show a fragment in a modal dialog. The existing page will remain
|
8442
8532
|
open in the background and reappear once the modal is closed.
|
8443
8533
|
|
8444
|
-
To open a modal, add an [`up-modal` attribute](/
|
8534
|
+
To open a modal, add an [`up-modal` attribute](/up-modal) to a link,
|
8445
8535
|
or call the Javascript functions [`up.modal.follow`](/up.modal.follow)
|
8446
8536
|
and [`up.modal.visit`](/up.modal.visit).
|
8447
8537
|
|
@@ -8481,7 +8571,7 @@ configure Unpoly to [use a different HTML structure](/up.modal.config).
|
|
8481
8571
|
\#\#\#\# Closing behavior
|
8482
8572
|
|
8483
8573
|
By default the dialog automatically closes
|
8484
|
-
*
|
8574
|
+
*when a link inside a modal changes a fragment behind the modal*.
|
8485
8575
|
This is useful to have the dialog interact with the page that
|
8486
8576
|
opened it, e.g. by updating parts of a larger form or by signing in a user
|
8487
8577
|
and revealing additional information.
|
@@ -8496,7 +8586,7 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
8496
8586
|
|
8497
8587
|
(function() {
|
8498
8588
|
up.modal = (function($) {
|
8499
|
-
var autoclose, close, config, contains, coveredUrl, createFrame, currentUrl, discardHistory, extract, follow, isOpen, open, reset, shiftElements, templateHtml, u, unshiftElements, unshifters, visit;
|
8589
|
+
var animate, autoclose, close, config, contains, coveredUrl, createFrame, currentFlavor, currentUrl, discardHistory, extract, flavor, flavorDefault, flavorOverrides, follow, isOpen, markAsAnimating, open, reset, shiftElements, templateHtml, u, unshiftElements, unshifters, visit;
|
8500
8590
|
u = up.util;
|
8501
8591
|
|
8502
8592
|
/**
|
@@ -8546,6 +8636,9 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
8546
8636
|
The timing function controlling the acceleration of the opening animation.
|
8547
8637
|
@param {String} [config.closeEasing]
|
8548
8638
|
The timing function controlling the acceleration of the closing animation.
|
8639
|
+
@param {Boolean} [options.sticky=false]
|
8640
|
+
If set to `true`, the modal remains
|
8641
|
+
open even it changes the page in the background.
|
8549
8642
|
@stable
|
8550
8643
|
*/
|
8551
8644
|
config = u.config({
|
@@ -8556,15 +8649,18 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
8556
8649
|
history: true,
|
8557
8650
|
openAnimation: 'fade-in',
|
8558
8651
|
closeAnimation: 'fade-out',
|
8559
|
-
closeDuration: null,
|
8560
|
-
closeEasing: null,
|
8561
8652
|
openDuration: null,
|
8653
|
+
closeDuration: null,
|
8562
8654
|
openEasing: null,
|
8655
|
+
closeEasing: null,
|
8563
8656
|
backdropOpenAnimation: 'fade-in',
|
8564
8657
|
backdropCloseAnimation: 'fade-out',
|
8565
8658
|
closeLabel: '×',
|
8659
|
+
flavors: {
|
8660
|
+
"default": {}
|
8661
|
+
},
|
8566
8662
|
template: function(config) {
|
8567
|
-
return "<div class=\"up-modal\">\n <div class=\"up-modal-backdrop\"></div>\n <div class=\"up-modal-viewport\">\n <div class=\"up-modal-dialog\">\n <div class=\"up-modal-close\" up-close>" +
|
8663
|
+
return "<div class=\"up-modal\">\n <div class=\"up-modal-backdrop\"></div>\n <div class=\"up-modal-viewport\">\n <div class=\"up-modal-dialog\">\n <div class=\"up-modal-content\"></div>\n <div class=\"up-modal-close\" up-close>" + (flavorDefault('closeLabel')) + "</div>\n </div>\n </div>\n</div>";
|
8568
8664
|
}
|
8569
8665
|
});
|
8570
8666
|
|
@@ -8578,6 +8674,7 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
8578
8674
|
@stable
|
8579
8675
|
*/
|
8580
8676
|
currentUrl = void 0;
|
8677
|
+
currentFlavor = void 0;
|
8581
8678
|
|
8582
8679
|
/**
|
8583
8680
|
Returns the URL of the page behind the modal overlay.
|
@@ -8594,11 +8691,12 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
8594
8691
|
animation: false
|
8595
8692
|
});
|
8596
8693
|
currentUrl = void 0;
|
8694
|
+
currentFlavor = void 0;
|
8597
8695
|
return config.reset();
|
8598
8696
|
};
|
8599
8697
|
templateHtml = function() {
|
8600
8698
|
var template;
|
8601
|
-
template =
|
8699
|
+
template = flavorDefault('template');
|
8602
8700
|
if (u.isFunction(template)) {
|
8603
8701
|
return template(config);
|
8604
8702
|
} else {
|
@@ -8612,57 +8710,69 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
8612
8710
|
return $modal.removeAttr('up-covered-title');
|
8613
8711
|
};
|
8614
8712
|
createFrame = function(target, options) {
|
8615
|
-
var
|
8616
|
-
|
8617
|
-
if (
|
8618
|
-
|
8619
|
-
|
8620
|
-
|
8621
|
-
$modal.attr('up-covered-title', document.title);
|
8622
|
-
$dialog = $modal.find('.up-modal-dialog');
|
8623
|
-
if (u.isPresent(options.width)) {
|
8624
|
-
$dialog.css('width', options.width);
|
8625
|
-
}
|
8626
|
-
if (u.isPresent(options.maxWidth)) {
|
8627
|
-
$dialog.css('max-width', options.maxWidth);
|
8628
|
-
}
|
8629
|
-
if (u.isPresent(options.height)) {
|
8630
|
-
$dialog.css('height', options.height);
|
8713
|
+
var promise;
|
8714
|
+
promise = u.resolvedPromise();
|
8715
|
+
if (isOpen()) {
|
8716
|
+
promise = promise.then(function() {
|
8717
|
+
return close();
|
8718
|
+
});
|
8631
8719
|
}
|
8632
|
-
|
8633
|
-
|
8634
|
-
|
8635
|
-
|
8720
|
+
promise = promise.then(function() {
|
8721
|
+
var $content, $dialog, $modal;
|
8722
|
+
currentFlavor = options.flavor;
|
8723
|
+
$modal = $(templateHtml());
|
8724
|
+
$modal.attr('up-flavor', currentFlavor);
|
8725
|
+
if (options.sticky) {
|
8726
|
+
$modal.attr('up-sticky', '');
|
8727
|
+
}
|
8728
|
+
$modal.attr('up-covered-url', up.browser.url());
|
8729
|
+
$modal.attr('up-covered-title', document.title);
|
8730
|
+
$dialog = $modal.find('.up-modal-dialog');
|
8731
|
+
if (u.isPresent(options.width)) {
|
8732
|
+
$dialog.css('width', options.width);
|
8733
|
+
}
|
8734
|
+
if (u.isPresent(options.maxWidth)) {
|
8735
|
+
$dialog.css('max-width', options.maxWidth);
|
8736
|
+
}
|
8737
|
+
if (u.isPresent(options.height)) {
|
8738
|
+
$dialog.css('height', options.height);
|
8739
|
+
}
|
8740
|
+
$content = $modal.find('.up-modal-content');
|
8741
|
+
u.$createPlaceholder(target, $content);
|
8742
|
+
return $modal.appendTo(document.body);
|
8743
|
+
});
|
8744
|
+
return promise;
|
8636
8745
|
};
|
8637
8746
|
unshifters = [];
|
8638
8747
|
shiftElements = function() {
|
8639
|
-
var bodyRightPadding, bodyRightShift, scrollbarWidth, unshiftBody;
|
8640
|
-
if (unshifters.length) {
|
8641
|
-
|
8642
|
-
}
|
8643
|
-
|
8644
|
-
|
8645
|
-
|
8646
|
-
|
8647
|
-
|
8648
|
-
|
8649
|
-
|
8650
|
-
|
8651
|
-
unshifters.push(unshiftBody);
|
8652
|
-
return up.layout.anchoredRight().each(function() {
|
8653
|
-
var $element, elementRight, elementRightShift, unshifter;
|
8654
|
-
$element = $(this);
|
8655
|
-
elementRight = parseInt($element.css('right'));
|
8656
|
-
elementRightShift = scrollbarWidth + elementRight;
|
8657
|
-
unshifter = u.temporaryCss($element, {
|
8658
|
-
'right': elementRightShift
|
8748
|
+
var $body, bodyRightPadding, bodyRightShift, scrollbarWidth, unshiftBody;
|
8749
|
+
if (unshifters.length > 0) {
|
8750
|
+
return;
|
8751
|
+
}
|
8752
|
+
if (u.documentHasVerticalScrollbar()) {
|
8753
|
+
$body = $('body');
|
8754
|
+
scrollbarWidth = u.scrollbarWidth();
|
8755
|
+
bodyRightPadding = parseInt($body.css('padding-right'));
|
8756
|
+
bodyRightShift = scrollbarWidth + bodyRightPadding;
|
8757
|
+
unshiftBody = u.temporaryCss($body, {
|
8758
|
+
'padding-right': bodyRightShift + "px",
|
8759
|
+
'overflow-y': 'hidden'
|
8659
8760
|
});
|
8660
|
-
|
8661
|
-
|
8761
|
+
unshifters.push(unshiftBody);
|
8762
|
+
return up.layout.anchoredRight().each(function() {
|
8763
|
+
var $element, elementRight, elementRightShift, unshifter;
|
8764
|
+
$element = $(this);
|
8765
|
+
elementRight = parseInt($element.css('right'));
|
8766
|
+
elementRightShift = scrollbarWidth + elementRight;
|
8767
|
+
unshifter = u.temporaryCss($element, {
|
8768
|
+
'right': elementRightShift
|
8769
|
+
});
|
8770
|
+
return unshifters.push(unshifter);
|
8771
|
+
});
|
8772
|
+
}
|
8662
8773
|
};
|
8663
8774
|
unshiftElements = function() {
|
8664
8775
|
var results, unshifter;
|
8665
|
-
$('.up-modal').removeClass('up-modal-ready');
|
8666
8776
|
results = [];
|
8667
8777
|
while (unshifter = unshifters.pop()) {
|
8668
8778
|
results.push(unshifter());
|
@@ -8673,6 +8783,8 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
8673
8783
|
/**
|
8674
8784
|
Returns whether a modal is currently open.
|
8675
8785
|
|
8786
|
+
This also returns `true` if the modal is in an opening or closing animation.
|
8787
|
+
|
8676
8788
|
@function up.modal.isOpen
|
8677
8789
|
@stable
|
8678
8790
|
*/
|
@@ -8703,7 +8815,7 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
8703
8815
|
By [default](/up.modal.config) the dialog will grow to fit its contents.
|
8704
8816
|
@param {Boolean} [options.sticky=false]
|
8705
8817
|
If set to `true`, the modal remains
|
8706
|
-
open even
|
8818
|
+
open even it changes the page in the background.
|
8707
8819
|
@param {String} [options.confirm]
|
8708
8820
|
A message that will be displayed in a cancelable confirmation dialog
|
8709
8821
|
before the modal is being opened.
|
@@ -8801,53 +8913,48 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
8801
8913
|
options = u.options(options);
|
8802
8914
|
$link = u.option(u.pluckKey(options, '$link'), u.nullJQuery());
|
8803
8915
|
url = u.option(u.pluckKey(options, 'url'), $link.attr('up-href'), $link.attr('href'));
|
8804
|
-
html = u.pluckKey(options, 'html');
|
8916
|
+
html = u.option(u.pluckKey(options, 'html'));
|
8805
8917
|
target = u.option(u.pluckKey(options, 'target'), $link.attr('up-modal'), 'body');
|
8806
|
-
options.
|
8807
|
-
options.
|
8808
|
-
options.
|
8809
|
-
options.
|
8810
|
-
options.
|
8811
|
-
options.
|
8918
|
+
options.flavor = u.option(options.flavor, $link.attr('up-flavor'));
|
8919
|
+
options.width = u.option(options.width, $link.attr('up-width'), flavorDefault('width', options.flavor));
|
8920
|
+
options.maxWidth = u.option(options.maxWidth, $link.attr('up-max-width'), flavorDefault('maxWidth', options.flavor));
|
8921
|
+
options.height = u.option(options.height, $link.attr('up-height'), flavorDefault('height'));
|
8922
|
+
options.animation = u.option(options.animation, $link.attr('up-animation'), flavorDefault('openAnimation', options.flavor));
|
8923
|
+
options.backdropAnimation = u.option(options.backdropAnimation, $link.attr('up-backdrop-animation'), flavorDefault('backdropOpenAnimation', options.flavor));
|
8924
|
+
options.sticky = u.option(options.sticky, u.castedAttr($link, 'up-sticky'), flavorDefault('sticky', options.flavor));
|
8812
8925
|
options.confirm = u.option(options.confirm, $link.attr('up-confirm'));
|
8813
8926
|
animateOptions = up.motion.animateOptions(options, $link, {
|
8814
|
-
duration:
|
8815
|
-
easing:
|
8927
|
+
duration: flavorDefault('openDuration', options.flavor),
|
8928
|
+
easing: flavorDefault('openEasing', options.flavor)
|
8816
8929
|
});
|
8817
|
-
options.history = u.option(options.history, u.castedAttr($link, 'up-history'),
|
8930
|
+
options.history = u.option(options.history, u.castedAttr($link, 'up-history'), flavorDefault('history', options.flavor));
|
8818
8931
|
if (!up.browser.canPushState()) {
|
8819
8932
|
options.history = false;
|
8820
8933
|
}
|
8821
8934
|
return up.browser.confirm(options).then(function() {
|
8822
|
-
var extractOptions, promise
|
8935
|
+
var extractOptions, promise;
|
8823
8936
|
if (up.bus.nobodyPrevents('up:modal:open', {
|
8824
8937
|
url: url,
|
8825
8938
|
message: 'Opening modal'
|
8826
8939
|
})) {
|
8827
|
-
wasOpen = isOpen();
|
8828
|
-
if (wasOpen) {
|
8829
|
-
close({
|
8830
|
-
animation: false
|
8831
|
-
});
|
8832
|
-
}
|
8833
8940
|
options.beforeSwap = function() {
|
8834
8941
|
return createFrame(target, options);
|
8835
8942
|
};
|
8836
8943
|
extractOptions = u.merge(options, {
|
8837
8944
|
animation: false
|
8838
8945
|
});
|
8839
|
-
if (
|
8840
|
-
promise = up.replace(target, url, extractOptions);
|
8841
|
-
} else {
|
8946
|
+
if (html) {
|
8842
8947
|
promise = up.extract(target, html, extractOptions);
|
8948
|
+
} else {
|
8949
|
+
promise = up.replace(target, url, extractOptions);
|
8843
8950
|
}
|
8844
|
-
if (!(wasOpen || up.motion.isNone(options.animation))) {
|
8845
|
-
promise = promise.then(function() {
|
8846
|
-
return $.when(up.animate($('.up-modal-backdrop'), options.backdropAnimation, animateOptions), up.animate($('.up-modal-viewport'), options.animation, animateOptions));
|
8847
|
-
});
|
8848
|
-
}
|
8849
8951
|
promise = promise.then(function() {
|
8850
|
-
shiftElements();
|
8952
|
+
return shiftElements();
|
8953
|
+
});
|
8954
|
+
promise = promise.then(function() {
|
8955
|
+
return animate(options.animation, options.backdropAnimation, animateOptions);
|
8956
|
+
});
|
8957
|
+
promise = promise.then(function() {
|
8851
8958
|
return up.emit('up:modal:opened', {
|
8852
8959
|
message: 'Modal opened'
|
8853
8960
|
});
|
@@ -8899,18 +9006,16 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
8899
9006
|
$element: $modal,
|
8900
9007
|
message: 'Closing modal'
|
8901
9008
|
})) {
|
8902
|
-
|
8903
|
-
|
8904
|
-
backdropCloseAnimation = u.option(options.backdropAnimation, config.backdropCloseAnimation);
|
9009
|
+
viewportCloseAnimation = u.option(options.animation, flavorDefault('closeAnimation'));
|
9010
|
+
backdropCloseAnimation = u.option(options.backdropAnimation, flavorDefault('backdropCloseAnimation'));
|
8905
9011
|
animateOptions = up.motion.animateOptions(options, {
|
8906
|
-
duration:
|
8907
|
-
easing:
|
9012
|
+
duration: flavorDefault('closeDuration'),
|
9013
|
+
easing: flavorDefault('closeEasing')
|
9014
|
+
});
|
9015
|
+
promise = u.resolvedPromise();
|
9016
|
+
promise = promise.then(function() {
|
9017
|
+
return animate(viewportCloseAnimation, backdropCloseAnimation, animateOptions);
|
8908
9018
|
});
|
8909
|
-
if (up.motion.isNone(viewportCloseAnimation)) {
|
8910
|
-
promise = u.resolvedPromise();
|
8911
|
-
} else {
|
8912
|
-
promise = $.when(up.animate($('.up-modal-viewport'), viewportCloseAnimation, animateOptions), up.animate($('.up-modal-backdrop'), backdropCloseAnimation, animateOptions));
|
8913
|
-
}
|
8914
9019
|
promise = promise.then(function() {
|
8915
9020
|
var destroyOptions;
|
8916
9021
|
destroyOptions = u.options(u.except(options, 'animation', 'duration', 'easing', 'delay'), {
|
@@ -8918,17 +9023,40 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
8918
9023
|
title: $modal.attr('up-covered-title')
|
8919
9024
|
});
|
8920
9025
|
currentUrl = void 0;
|
8921
|
-
up.destroy($modal, destroyOptions);
|
9026
|
+
return up.destroy($modal, destroyOptions);
|
9027
|
+
});
|
9028
|
+
promise = promise.then(function() {
|
9029
|
+
unshiftElements();
|
9030
|
+
currentFlavor = void 0;
|
8922
9031
|
return up.emit('up:modal:closed', {
|
8923
9032
|
message: 'Modal closed'
|
8924
9033
|
});
|
8925
9034
|
});
|
8926
9035
|
return promise;
|
8927
9036
|
} else {
|
8928
|
-
return u.
|
9037
|
+
return u.unresolvablePromise();
|
8929
9038
|
}
|
8930
9039
|
} else {
|
8931
|
-
return u.
|
9040
|
+
return u.resolvedPromise();
|
9041
|
+
}
|
9042
|
+
};
|
9043
|
+
markAsAnimating = function(state) {
|
9044
|
+
if (state == null) {
|
9045
|
+
state = true;
|
9046
|
+
}
|
9047
|
+
return $('.up-modal').toggleClass('up-modal-animating', state);
|
9048
|
+
};
|
9049
|
+
animate = function(viewportAnimation, backdropAnimation, animateOptions) {
|
9050
|
+
var promise;
|
9051
|
+
if (up.motion.isNone(viewportAnimation)) {
|
9052
|
+
return u.resolvedPromise();
|
9053
|
+
} else {
|
9054
|
+
markAsAnimating();
|
9055
|
+
promise = $.when(up.animate($('.up-modal-viewport'), viewportAnimation, animateOptions), up.animate($('.up-modal-backdrop'), backdropAnimation, animateOptions));
|
9056
|
+
promise = promise.then(function() {
|
9057
|
+
return markAsAnimating(false);
|
9058
|
+
});
|
9059
|
+
return promise;
|
8932
9060
|
}
|
8933
9061
|
};
|
8934
9062
|
|
@@ -8970,6 +9098,81 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
8970
9098
|
return $element.closest('.up-modal').length > 0;
|
8971
9099
|
};
|
8972
9100
|
|
9101
|
+
/**
|
9102
|
+
Register a new modal variant with its own default configuration, CSS or HTML template.
|
9103
|
+
|
9104
|
+
\#\#\#\# Example
|
9105
|
+
|
9106
|
+
Let's implement a drawer that slides in from the right:
|
9107
|
+
|
9108
|
+
up.modal.flavor('drawer', {
|
9109
|
+
openAnimation: 'move-from-right',
|
9110
|
+
closeAnimation: 'move-to-right',
|
9111
|
+
maxWidth: 400
|
9112
|
+
}
|
9113
|
+
|
9114
|
+
Modals with that flavor will have a container `<div class='up-modal' up-flavor='drawer'>...</div>`.
|
9115
|
+
We can target the `up-flavor` attribute override the default dialog styles:
|
9116
|
+
|
9117
|
+
.up-modal[up-flavor='drawer'] {
|
9118
|
+
|
9119
|
+
// Align drawer on the right
|
9120
|
+
.up-modal-viewport { text-align: right; }
|
9121
|
+
|
9122
|
+
// Remove margin so the drawer starts at the screen edge
|
9123
|
+
.up-modal-dialog { margin: 0; }
|
9124
|
+
|
9125
|
+
// Stretch drawer background to full window height
|
9126
|
+
.up-modal-content { min-height: 100vh; }
|
9127
|
+
}
|
9128
|
+
|
9129
|
+
@function up.modal.flavor
|
9130
|
+
@param {String} name
|
9131
|
+
The name of the new flavor.
|
9132
|
+
@param {Object} [overrideConfig]
|
9133
|
+
An object whose properties override the defaults in [`/up.modal.config`](/up.modal.config).
|
9134
|
+
@experimental
|
9135
|
+
*/
|
9136
|
+
flavor = function(name, overrideConfig) {
|
9137
|
+
if (overrideConfig == null) {
|
9138
|
+
overrideConfig = {};
|
9139
|
+
}
|
9140
|
+
return u.extend(flavorOverrides(name), overrideConfig);
|
9141
|
+
};
|
9142
|
+
|
9143
|
+
/**
|
9144
|
+
Returns a config object for the given flavor.
|
9145
|
+
Properties in that config should be preferred to the defaults in
|
9146
|
+
[`/up.modal.config`](/up.modal.config).
|
9147
|
+
|
9148
|
+
@function flavorOverrides
|
9149
|
+
@internal
|
9150
|
+
*/
|
9151
|
+
flavorOverrides = function(flavor) {
|
9152
|
+
var base;
|
9153
|
+
return (base = config.flavors)[flavor] || (base[flavor] = {});
|
9154
|
+
};
|
9155
|
+
|
9156
|
+
/**
|
9157
|
+
Returns the config option for the current flavor.
|
9158
|
+
|
9159
|
+
@function flavorDefault
|
9160
|
+
@internal
|
9161
|
+
*/
|
9162
|
+
flavorDefault = function(key, flavorName) {
|
9163
|
+
var value;
|
9164
|
+
if (flavorName == null) {
|
9165
|
+
flavorName = currentFlavor;
|
9166
|
+
}
|
9167
|
+
if (flavorName) {
|
9168
|
+
value = flavorOverrides(flavorName)[key];
|
9169
|
+
}
|
9170
|
+
if (u.isMissing(value)) {
|
9171
|
+
value = config[key];
|
9172
|
+
}
|
9173
|
+
return value;
|
9174
|
+
};
|
9175
|
+
|
8973
9176
|
/**
|
8974
9177
|
Clicking this link will load the destination via AJAX and open
|
8975
9178
|
the given selector in a modal dialog.
|
@@ -8983,7 +9186,7 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
8983
9186
|
and place the matching `.blog-list` tag will be placed in
|
8984
9187
|
a modal dialog.
|
8985
9188
|
|
8986
|
-
@selector
|
9189
|
+
@selector [up-modal]
|
8987
9190
|
@param {String} [up-confirm]
|
8988
9191
|
A message that will be displayed in a cancelable confirmation dialog
|
8989
9192
|
before the modal is opened.
|
@@ -8997,11 +9200,12 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
8997
9200
|
@param {String} [up-height]
|
8998
9201
|
The width of the dialog in pixels.
|
8999
9202
|
By [default](/up.modal.config) the dialog will grow to fit its contents.
|
9000
|
-
@param [up-width]
|
9203
|
+
@param {String} [up-width]
|
9001
9204
|
The width of the dialog in pixels.
|
9002
9205
|
By [default](/up.modal.config) the dialog will grow to fit its contents.
|
9003
|
-
@param [up-history="true"]
|
9206
|
+
@param {String} [up-history="true"]
|
9004
9207
|
Whether to add a browser history entry for the modal's source URL.
|
9208
|
+
|
9005
9209
|
@stable
|
9006
9210
|
*/
|
9007
9211
|
up.link.onAction('[up-modal]', function($link) {
|
@@ -9069,7 +9273,8 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
9069
9273
|
source: function() {
|
9070
9274
|
return up.error('up.modal.source no longer exists. Please use up.popup.url instead.');
|
9071
9275
|
},
|
9072
|
-
isOpen: isOpen
|
9276
|
+
isOpen: isOpen,
|
9277
|
+
flavor: flavor
|
9073
9278
|
};
|
9074
9279
|
})(jQuery);
|
9075
9280
|
|
@@ -9313,6 +9518,8 @@ by providing instant feedback for user interactions.
|
|
9313
9518
|
*/
|
9314
9519
|
|
9315
9520
|
(function() {
|
9521
|
+
var slice = [].slice;
|
9522
|
+
|
9316
9523
|
up.navigation = (function($) {
|
9317
9524
|
var CLASS_ACTIVE, SELECTOR_SECTION, config, currentClass, findClickArea, locationChanged, markActive, normalizeUrl, reset, sectionUrls, u, unmarkActive, urlSet, withActiveMark;
|
9318
9525
|
u = up.util;
|
@@ -9466,8 +9673,11 @@ by providing instant feedback for user interactions.
|
|
9466
9673
|
$element = findClickArea(elementOrSelector, options);
|
9467
9674
|
return $element.removeClass(CLASS_ACTIVE);
|
9468
9675
|
};
|
9469
|
-
withActiveMark = function(
|
9470
|
-
var $element, promise;
|
9676
|
+
withActiveMark = function() {
|
9677
|
+
var $element, args, block, elementOrSelector, options, promise;
|
9678
|
+
elementOrSelector = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
9679
|
+
block = args.pop();
|
9680
|
+
options = u.options(args.pop());
|
9471
9681
|
$element = $(elementOrSelector);
|
9472
9682
|
markActive($element, options);
|
9473
9683
|
promise = block();
|