unpoly-rails 0.24.1 → 0.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of unpoly-rails might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +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();
|