unpoly-rails 0.55.1 → 0.56.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 +59 -2
- data/dist/unpoly-bootstrap3.js +6 -4
- data/dist/unpoly-bootstrap3.min.js +1 -1
- data/dist/unpoly.js +1323 -805
- data/dist/unpoly.min.js +4 -3
- data/lib/assets/javascripts/unpoly-bootstrap3/{navigation-ext.coffee → feedback-ext.coffee} +2 -0
- data/lib/assets/javascripts/unpoly/browser.coffee.erb +7 -7
- data/lib/assets/javascripts/unpoly/bus.coffee.erb +5 -6
- data/lib/assets/javascripts/unpoly/classes/css_transition.coffee +127 -0
- data/lib/assets/javascripts/unpoly/classes/extract_plan.coffee +1 -1
- data/lib/assets/javascripts/unpoly/classes/motion_tracker.coffee +62 -32
- data/lib/assets/javascripts/unpoly/classes/url_set.coffee +27 -0
- data/lib/assets/javascripts/unpoly/dom.coffee.erb +78 -99
- data/lib/assets/javascripts/unpoly/feedback.coffee +147 -96
- data/lib/assets/javascripts/unpoly/form.coffee.erb +26 -2
- data/lib/assets/javascripts/unpoly/history.coffee +2 -1
- data/lib/assets/javascripts/unpoly/layout.coffee.erb +68 -12
- data/lib/assets/javascripts/unpoly/link.coffee.erb +10 -4
- data/lib/assets/javascripts/unpoly/modal.coffee.erb +11 -9
- data/lib/assets/javascripts/unpoly/{motion.coffee → motion.coffee.erb} +184 -322
- data/lib/assets/javascripts/unpoly/popup.coffee.erb +13 -12
- data/lib/assets/javascripts/unpoly/radio.coffee +1 -1
- data/lib/assets/javascripts/unpoly/syntax.coffee +8 -17
- data/lib/assets/javascripts/unpoly/tooltip.coffee +11 -11
- data/lib/assets/javascripts/unpoly/util.coffee +332 -145
- data/lib/unpoly/rails/version.rb +1 -1
- data/package.json +1 -1
- data/spec_app/Gemfile.lock +1 -1
- data/spec_app/app/assets/javascripts/integration_test.coffee +1 -0
- data/spec_app/app/assets/stylesheets/integration_test.sass +1 -0
- data/spec_app/app/assets/stylesheets/jasmine_specs.sass +4 -0
- data/spec_app/app/views/motion_test/transitions.erb +13 -0
- data/spec_app/app/views/pages/start.erb +1 -0
- data/spec_app/spec/javascripts/helpers/to_be_attached.coffee +5 -0
- data/spec_app/spec/javascripts/helpers/to_be_detached.coffee +5 -0
- data/spec_app/spec/javascripts/helpers/to_contain.js.coffee +1 -1
- data/spec_app/spec/javascripts/helpers/to_have_opacity.coffee +11 -0
- data/spec_app/spec/javascripts/helpers/to_have_own_property.js.coffee +5 -0
- data/spec_app/spec/javascripts/up/dom_spec.js.coffee +217 -102
- data/spec_app/spec/javascripts/up/feedback_spec.js.coffee +162 -44
- data/spec_app/spec/javascripts/up/layout_spec.js.coffee +97 -10
- data/spec_app/spec/javascripts/up/link_spec.js.coffee +3 -3
- data/spec_app/spec/javascripts/up/modal_spec.js.coffee +22 -20
- data/spec_app/spec/javascripts/up/motion_spec.js.coffee +344 -228
- data/spec_app/spec/javascripts/up/popup_spec.js.coffee +1 -1
- data/spec_app/spec/javascripts/up/syntax_spec.js.coffee +1 -1
- data/spec_app/spec/javascripts/up/tooltip_spec.js.coffee +1 -1
- data/spec_app/spec/javascripts/up/util_spec.js.coffee +194 -0
- metadata +11 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d87f0c7ddd74397b5396ee163bc18cb2579bb251942c6510507ba979f84e9e3a
|
4
|
+
data.tar.gz: 1418a2cc65b35e9104f907e44e583e6000253a8d0c08bf577975a2323941e8d6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 03477e7f970484239d5a0d534849b0667c10e50cbfa9b0d29925a3725d7abcc57a8f5e7f805278237aec0e6be159ce8bfe1c71f6d2ae956e3a2dc7078b14b689
|
7
|
+
data.tar.gz: 68c3eb323cc58e8a1f3c9724292377a282e79340dffaf347fbd603cb9e80deac864087a175f03739577f83b3aea059a8c89f5a09ee1d3f0339c7200987314467
|
data/CHANGELOG.md
CHANGED
@@ -6,11 +6,68 @@ Changes to this project will be documented in this file.
|
|
6
6
|
This project mostly adheres to [Semantic Versioning](http://semver.org/).
|
7
7
|
|
8
8
|
|
9
|
+
0.56.0
|
10
|
+
------
|
11
|
+
|
12
|
+
This release includes major performance improvements and a new animation engine.
|
13
|
+
|
14
|
+
Beware of the breaking change with [`.up-current`](/up-nav-a.up-current)!
|
15
|
+
|
16
|
+
|
17
|
+
### Navigation feedback
|
18
|
+
|
19
|
+
Maintaining the [`.up-current`](/up-nav-a.up-current) on all links turned out to be a major performance bottleneck, so we had to make some breaking changes:
|
20
|
+
|
21
|
+
- The [`.up-current`](/up-nav-a.up-current) class is now only assigned to links with an [`[up-nav]`](/up-nav) attribute, or to links within a container with an [`[up-nav]`](/up-nav) attribute. You should assign the [`[up-nav]`](/up-nav) attribute to all navigational elements that rely on `.up-current` for styling`.
|
22
|
+
- You can also globally configure selectors for your navigational elements in `up.feedback.config.navs`:
|
23
|
+
|
24
|
+
up.feedback.config.navs.push('.my-nav-bar')
|
25
|
+
- The normalized URLs of [`[up-nav]`](/up-nav) links are now cached for performance reasons.
|
26
|
+
- [`[up-nav]`](/up-nav) links are only updated once when multiple fragments are updated in a single [replacement](/a-up-target).
|
27
|
+
|
28
|
+
|
29
|
+
### Animation
|
30
|
+
|
31
|
+
- When performing an [animated page transition](/up.motion) Unpoly will no longer create copies of the old and new fragment versions. The animation will instead be performed on the original fragment versions.
|
32
|
+
- When animating an element with an existing [CSS transition](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions), Unpoly will now pause the CSS transition in its current state, perform the animation, then resume the CSS transition.
|
33
|
+
- Unpoly now does less work when animation is disabled globally through `up.motion.config.enabled = false`.
|
34
|
+
- [`up.morph()`](/up.morph) will now expect the new fragment version to be detached from the DOM before morphing.
|
35
|
+
- [`up.morph()`](/up.morph) will now detach the old fragment version from the DOM after morphing.
|
36
|
+
- The [`up.morph()`](/up.morph) function has been demoted from *stable* to *experimental*.
|
37
|
+
- [`up.motion.finish()`](/up.motion.finish) now longer queries the DOM when there are no active animations.
|
38
|
+
|
39
|
+
|
40
|
+
### Application layout
|
41
|
+
|
42
|
+
- When Unpoly cannot find the viewport of an element, it will now always considers `document` to be the viewport.
|
43
|
+
|
44
|
+
|
45
|
+
### Fragment updates
|
46
|
+
|
47
|
+
- The [`up:fragment:destroyed`](/up:fragment:destroyed) event is now emitted after the fragment has been removed from the DOM. The event is emitted on the former parent of the removed fragment.
|
48
|
+
|
49
|
+
|
50
|
+
### Utility functions
|
51
|
+
|
52
|
+
- Fix a bug where `up.util.isBlank()` returned `true` for a function value
|
53
|
+
|
54
|
+
|
55
|
+
### General
|
56
|
+
|
57
|
+
- Partially remove jQuery from internal code for performance reasons. We want to eventually remove jQuery as a dependency.
|
58
|
+
- Cache the results of feature detection for performance reasons.
|
59
|
+
- Unpoly is now more efficient when selecting elements from the DOM.
|
60
|
+
- Unpoly is now more efficient when reacting to mouse events.
|
61
|
+
|
62
|
+
|
63
|
+
|
9
64
|
0.55.1
|
10
65
|
------
|
11
66
|
|
12
67
|
This release restores support for Internet Explorer 11, which we accidentally broke in 0.55.0.
|
13
68
|
|
69
|
+
Thanks to [@foobear](https://github.com/foobear) for helping with this.
|
70
|
+
|
14
71
|
|
15
72
|
0.55.0
|
16
73
|
------
|
@@ -44,7 +101,7 @@ This release restores support for Internet Explorer 11, which we accidentally br
|
|
44
101
|
|
45
102
|
This release contains no new features, but will help you when using tools like Babel or Webpack:
|
46
103
|
|
47
|
-
- Unpoly now ship without any uses of [`eval()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval) in its JavaScript sources. Use of `eval()` had previously prevented minifiers from shortening local variables in some files.
|
104
|
+
- Unpoly now ship without any uses of [`eval()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval) in its JavaScript sources. Use of `eval()` had previously prevented minifiers from shortening local variables in some files.
|
48
105
|
- Documentation in Unpoly's JavaScript sources can no longer be confused with [JSDoc](http://usejsdoc.org/) comments. Unpoly does not use JSDoc, but some build pipelines eagerly look for JSDoc comments to generate type information.
|
49
106
|
|
50
107
|
|
@@ -143,7 +200,7 @@ This release contains no new features, but will help you when using tools like B
|
|
143
200
|
- Fix a bug where the animation `move-from-top` would finish instantly after animating with `move-to-top`.
|
144
201
|
- Fix a bug where the animation `move-from-right` would finish instantly after animating with `move-to-right`.
|
145
202
|
- Fix a bug where the animation `move-from-bottom` would finish instantly after animating with `move-to-bottom`.
|
146
|
-
- Fix a bug where the animation `move-from-left` would finish instantly after animating with `move-to-left
|
203
|
+
- Fix a bug where the animation `move-from-left` would finish instantly after animating with `move-to-left`
|
147
204
|
|
148
205
|
|
149
206
|
0.53.0
|
data/dist/unpoly-bootstrap3.js
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
(function() {
|
2
|
+
up.feedback.config.currentClasses.push('active');
|
3
|
+
|
4
|
+
up.feedback.config.navSelectors.push('.nav');
|
5
|
+
|
6
|
+
}).call(this);
|
1
7
|
(function() {
|
2
8
|
up.form.config.validateTargets.unshift('.form-group:has(&)');
|
3
9
|
|
@@ -17,10 +23,6 @@
|
|
17
23
|
(function() {
|
18
24
|
up.modal.config.template = "<div class=\"up-modal\">\n <div class=\"up-modal-backdrop\"></div>\n <div class=\"up-modal-viewport\">\n <div class=\"up-modal-dialog modal-dialog\">\n <div class=\"up-modal-content modal-content\"></div>\n </div>\n </div>\n</div>";
|
19
25
|
|
20
|
-
}).call(this);
|
21
|
-
(function() {
|
22
|
-
up.feedback.config.currentClasses.push('active');
|
23
|
-
|
24
26
|
}).call(this);
|
25
27
|
(function() {
|
26
28
|
|
@@ -1 +1 @@
|
|
1
|
-
(function(){up.form.config.validateTargets.unshift(".form-group:has(&)")}
|
1
|
+
(function(){up.feedback.config.currentClasses.push("active"),up.feedback.config.navSelectors.push(".nav")}).call(this),function(){up.form.config.validateTargets.unshift(".form-group:has(&)")}.call(this),function(){up.layout.config.fixedTop.push(".navbar-fixed-top"),up.layout.config.fixedBottom.push(".navbar-fixed-bottom"),up.layout.config.anchoredRight.push(".navbar-fixed-top"),up.layout.config.anchoredRight.push(".navbar-fixed-bottom"),up.layout.config.anchoredRight.push(".footer")}.call(this),function(){up.modal.config.template='<div class="up-modal">\n <div class="up-modal-backdrop"></div>\n <div class="up-modal-viewport">\n <div class="up-modal-dialog modal-dialog">\n <div class="up-modal-content modal-content"></div>\n </div>\n </div>\n</div>'}.call(this),function(){}.call(this);
|
data/dist/unpoly.js
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
(function() {
|
7
7
|
window.up = {
|
8
|
-
version: "0.
|
8
|
+
version: "0.56.0",
|
9
9
|
renamedModule: function(oldName, newName) {
|
10
10
|
return typeof Object.defineProperty === "function" ? Object.defineProperty(up, oldName, {
|
11
11
|
get: function() {
|
@@ -41,8 +41,18 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
41
41
|
@function up.util.noop
|
42
42
|
@experimental
|
43
43
|
*/
|
44
|
-
var $createElementFromSelector, $createPlaceholder, $submittingButton, DivertibleChain, ESCAPE_HTML_ENTITY_MAP, all, always, any, appendRequestData, assign, assignPolyfill, attributeSelector, castedAttr, clientSize, compact, config, contains, copy, copyAttributes, createElementFromHtml,
|
45
|
-
noop =
|
44
|
+
var $createElementFromSelector, $createPlaceholder, $submittingButton, CASE_CONVERSION_GROUP, CSS_LENGTH_PROPS, DivertibleChain, ESCAPE_HTML_ENTITY_MAP, addClass, addTemporaryClass, all, always, any, appendRequestData, arrayToSet, assign, assignPolyfill, asyncNoop, attributeSelector, camelCase, camelCaseKeys, castedAttr, changeClassList, clientSize, compact, concludeCssTransition, config, contains, convertCase, copy, copyAttributes, copyWithRenamedKeys, createElementFromHtml, cssLength, detachWith, detect, documentHasVerticalScrollbar, each, escapeHtml, escapePressed, evalOption, except, extractFromStyleObject, extractOptions, fail, fixedToAbsolute, flatten, forceRepaint, getElement, hasClass, hasCssTransition, hide, horizontalScreenHalf, identity, intersect, isArray, isBlank, isBodyDescendant, isCrossDomain, isDefined, isDetached, isElement, isEqual, isFixed, isFormData, isFunction, isGiven, isJQuery, isMissing, isNull, isNumber, isObject, isOptions, isPresent, isPromise, isStandardPort, isString, isTruthy, isUndefined, isUnmodifiedKeyEvent, isUnmodifiedMouseEvent, kebabCase, kebabCaseKeys, last, listBlock, map, margins, measure, memoize, merge, mergeRequestData, methodAllowsPayload, microtask, muteRejection, newDeferred, nextFrame, nonUpClasses, noop, normalizeMethod, normalizeStyleValueForWrite, normalizeUrl, nullJQuery, offsetParent, only, opacity, openConfig, option, options, parseUrl, pluckData, pluckKey, presence, presentAttr, previewable, promiseTimer, readComputedStyle, readComputedStyleNumber, readInlineStyle, reject, rejectOnError, remove, removeClass, renameKey, requestDataAsArray, requestDataAsQuery, requestDataFromForm, scrollbarWidth, select, selectInDynasty, selectInSubtree, selectorForElement, sequence, setMissingAttrs, setTimer, setToArray, submittedValue, times, toArray, trim, uniq, uniqBy, unresolvablePromise, unwrapElement, whenReady, writeInlineStyle, writeTemporaryStyle;
|
45
|
+
noop = (function() {});
|
46
|
+
|
47
|
+
/***
|
48
|
+
A function that returns a resolved promise.
|
49
|
+
|
50
|
+
@function up.util.asyncNoop
|
51
|
+
@internal
|
52
|
+
*/
|
53
|
+
asyncNoop = function() {
|
54
|
+
return Promise.resolve();
|
55
|
+
};
|
46
56
|
|
47
57
|
/***
|
48
58
|
Ensures that the given function can only be called a single time.
|
@@ -141,7 +151,9 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
141
151
|
*/
|
142
152
|
parseUrl = function(urlOrAnchor) {
|
143
153
|
var anchor;
|
144
|
-
|
154
|
+
if (isJQuery(urlOrAnchor)) {
|
155
|
+
urlOrAnchor = getElement(urlOrAnchor);
|
156
|
+
}
|
145
157
|
if (urlOrAnchor.pathname) {
|
146
158
|
return urlOrAnchor;
|
147
159
|
}
|
@@ -179,17 +191,17 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
179
191
|
@internal
|
180
192
|
*/
|
181
193
|
$createElementFromSelector = function(selector) {
|
182
|
-
var $element, $parent, $root, classes, conjunction, depthSelector, expression, html,
|
194
|
+
var $element, $parent, $root, classes, conjunction, depthSelector, expression, html, id, iteration, j, l, len, len1, path, tag;
|
183
195
|
path = selector.split(/[ >]/);
|
184
196
|
$root = null;
|
185
|
-
for (iteration =
|
197
|
+
for (iteration = j = 0, len = path.length; j < len; iteration = ++j) {
|
186
198
|
depthSelector = path[iteration];
|
187
199
|
conjunction = depthSelector.match(/(^|\.|\#)[A-Za-z0-9\-_]+/g);
|
188
200
|
tag = "div";
|
189
201
|
classes = [];
|
190
202
|
id = null;
|
191
|
-
for (
|
192
|
-
expression = conjunction[
|
203
|
+
for (l = 0, len1 = conjunction.length; l < len1; l++) {
|
204
|
+
expression = conjunction[l];
|
193
205
|
switch (expression[0]) {
|
194
206
|
case ".":
|
195
207
|
classes.push(expression.substr(1));
|
@@ -222,7 +234,8 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
222
234
|
};
|
223
235
|
|
224
236
|
/***
|
225
|
-
@function $
|
237
|
+
@function $createPlaceHolder
|
238
|
+
@internal
|
226
239
|
*/
|
227
240
|
$createPlaceholder = function(selector, container) {
|
228
241
|
var $placeholder;
|
@@ -252,7 +265,7 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
252
265
|
@experimental
|
253
266
|
*/
|
254
267
|
selectorForElement = function(element) {
|
255
|
-
var $element, ariaLabel, classes,
|
268
|
+
var $element, ariaLabel, classes, id, j, klass, len, name, selector, tagName, upId;
|
256
269
|
$element = $(element);
|
257
270
|
selector = void 0;
|
258
271
|
tagName = $element.prop('tagName').toLowerCase();
|
@@ -268,8 +281,8 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
268
281
|
selector = tagName + attributeSelector('name', name);
|
269
282
|
} else if (classes = presence(nonUpClasses($element))) {
|
270
283
|
selector = '';
|
271
|
-
for (
|
272
|
-
klass = classes[
|
284
|
+
for (j = 0, len = classes.length; j < len; j++) {
|
285
|
+
klass = classes[j];
|
273
286
|
selector += "." + klass;
|
274
287
|
}
|
275
288
|
} else if (ariaLabel = presence($element.attr("aria-label"))) {
|
@@ -297,10 +310,10 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
297
310
|
return parser.parseFromString(html, 'text/html');
|
298
311
|
};
|
299
312
|
assignPolyfill = function() {
|
300
|
-
var
|
313
|
+
var j, key, len, source, sources, target, value;
|
301
314
|
target = arguments[0], sources = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
302
|
-
for (
|
303
|
-
source = sources[
|
315
|
+
for (j = 0, len = sources.length; j < len; j++) {
|
316
|
+
source = sources[j];
|
304
317
|
for (key in source) {
|
305
318
|
if (!hasProp.call(source, key)) continue;
|
306
319
|
value = source[key];
|
@@ -356,10 +369,13 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
356
369
|
@stable
|
357
370
|
*/
|
358
371
|
map = function(array, block) {
|
359
|
-
var
|
372
|
+
var index, item, j, len, results;
|
373
|
+
if (array.length === 0) {
|
374
|
+
return [];
|
375
|
+
}
|
360
376
|
block = listBlock(block);
|
361
377
|
results = [];
|
362
|
-
for (index =
|
378
|
+
for (index = j = 0, len = array.length; j < len; index = ++j) {
|
363
379
|
item = array[index];
|
364
380
|
results.push(block(item, index));
|
365
381
|
}
|
@@ -387,9 +403,9 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
387
403
|
@stable
|
388
404
|
*/
|
389
405
|
times = function(count, block) {
|
390
|
-
var
|
406
|
+
var iteration, j, ref, results;
|
391
407
|
results = [];
|
392
|
-
for (iteration =
|
408
|
+
for (iteration = j = 0, ref = count - 1; 0 <= ref ? j <= ref : j >= ref; iteration = 0 <= ref ? ++j : --j) {
|
393
409
|
results.push(block(iteration));
|
394
410
|
}
|
395
411
|
return results;
|
@@ -482,7 +498,19 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
482
498
|
@stable
|
483
499
|
*/
|
484
500
|
isBlank = function(object) {
|
485
|
-
|
501
|
+
if (isMissing(object)) {
|
502
|
+
return true;
|
503
|
+
}
|
504
|
+
if (isFunction(object)) {
|
505
|
+
return false;
|
506
|
+
}
|
507
|
+
if (isObject(object) && Object.keys(object).length === 0) {
|
508
|
+
return true;
|
509
|
+
}
|
510
|
+
if (object.length === 0) {
|
511
|
+
return true;
|
512
|
+
}
|
513
|
+
return false;
|
486
514
|
};
|
487
515
|
|
488
516
|
/***
|
@@ -683,16 +711,20 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
683
711
|
};
|
684
712
|
|
685
713
|
/***
|
686
|
-
If given a jQuery collection, returns the
|
714
|
+
If given a jQuery collection, returns the first native DOM element in the collection.
|
715
|
+
If given a string, returns the first element matching that string.
|
687
716
|
If given any other argument, returns the argument unchanged.
|
688
717
|
|
689
|
-
@function up.util.
|
690
|
-
@param object
|
718
|
+
@function up.util.element
|
719
|
+
@param {jQuery|Element|String} object
|
720
|
+
@return {Element}
|
691
721
|
@internal
|
692
722
|
*/
|
693
|
-
|
723
|
+
getElement = function(object) {
|
694
724
|
if (isJQuery(object)) {
|
695
725
|
return object.get(0);
|
726
|
+
} else if (isString(object)) {
|
727
|
+
return $(object).get(0);
|
696
728
|
} else {
|
697
729
|
return object;
|
698
730
|
}
|
@@ -731,11 +763,10 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
731
763
|
for (key in defaults) {
|
732
764
|
defaultValue = defaults[key];
|
733
765
|
value = merged[key];
|
734
|
-
if (
|
735
|
-
|
736
|
-
} else if (isObject(defaultValue) && isObject(value)) {
|
737
|
-
merged[key] = options(value, defaultValue);
|
766
|
+
if (isMissing(value)) {
|
767
|
+
value = defaultValue;
|
738
768
|
}
|
769
|
+
merged[key] = value;
|
739
770
|
}
|
740
771
|
}
|
741
772
|
return merged;
|
@@ -771,10 +802,10 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
771
802
|
@stable
|
772
803
|
*/
|
773
804
|
detect = function(array, tester) {
|
774
|
-
var element,
|
805
|
+
var element, j, len, match;
|
775
806
|
match = void 0;
|
776
|
-
for (
|
777
|
-
element = array[
|
807
|
+
for (j = 0, len = array.length; j < len; j++) {
|
808
|
+
element = array[j];
|
778
809
|
if (tester(element)) {
|
779
810
|
match = element;
|
780
811
|
break;
|
@@ -796,10 +827,10 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
796
827
|
@experimental
|
797
828
|
*/
|
798
829
|
any = function(array, tester) {
|
799
|
-
var element,
|
830
|
+
var element, index, j, len, match;
|
800
831
|
tester = listBlock(tester);
|
801
832
|
match = false;
|
802
|
-
for (index =
|
833
|
+
for (index = j = 0, len = array.length; j < len; index = ++j) {
|
803
834
|
element = array[index];
|
804
835
|
if (tester(element, index)) {
|
805
836
|
match = true;
|
@@ -822,10 +853,10 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
822
853
|
@experimental
|
823
854
|
*/
|
824
855
|
all = function(array, tester) {
|
825
|
-
var element,
|
856
|
+
var element, index, j, len, match;
|
826
857
|
tester = listBlock(tester);
|
827
858
|
match = true;
|
828
|
-
for (index =
|
859
|
+
for (index = j = 0, len = array.length; j < len; index = ++j) {
|
829
860
|
element = array[index];
|
830
861
|
if (!tester(element, index)) {
|
831
862
|
match = false;
|
@@ -857,15 +888,10 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
857
888
|
@stable
|
858
889
|
*/
|
859
890
|
uniq = function(array) {
|
860
|
-
var set;
|
861
891
|
if (array.length < 2) {
|
862
892
|
return array;
|
863
893
|
}
|
864
|
-
|
865
|
-
each(array, function(element) {
|
866
|
-
return set.add(element);
|
867
|
-
});
|
868
|
-
return setToArray(set);
|
894
|
+
return setToArray(arrayToSet(array));
|
869
895
|
};
|
870
896
|
|
871
897
|
/**
|
@@ -911,6 +937,19 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
911
937
|
return array;
|
912
938
|
};
|
913
939
|
|
940
|
+
/**
|
941
|
+
@function up.util.arrayToSet
|
942
|
+
@internal
|
943
|
+
*/
|
944
|
+
arrayToSet = function(array) {
|
945
|
+
var set;
|
946
|
+
set = new Set();
|
947
|
+
array.forEach(function(elem) {
|
948
|
+
return set.add(elem);
|
949
|
+
});
|
950
|
+
return set;
|
951
|
+
};
|
952
|
+
|
914
953
|
/***
|
915
954
|
Returns all elements from the given array that return
|
916
955
|
a truthy value when passed to the given function.
|
@@ -963,6 +1002,34 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
963
1002
|
return contains(array2, element);
|
964
1003
|
});
|
965
1004
|
};
|
1005
|
+
addClass = function(element, klassOrKlasses) {
|
1006
|
+
return changeClassList(element, klassOrKlasses, 'add');
|
1007
|
+
};
|
1008
|
+
removeClass = function(element, klassOrKlasses) {
|
1009
|
+
return changeClassList(element, klassOrKlasses, 'remove');
|
1010
|
+
};
|
1011
|
+
changeClassList = function(element, klassOrKlasses, fnName) {
|
1012
|
+
var classList;
|
1013
|
+
classList = getElement(element).classList;
|
1014
|
+
if (isArray(klassOrKlasses)) {
|
1015
|
+
return each(klassOrKlasses, function(klass) {
|
1016
|
+
return classList[fnName](klass);
|
1017
|
+
});
|
1018
|
+
} else {
|
1019
|
+
return classList[fnName](klassOrKlasses);
|
1020
|
+
}
|
1021
|
+
};
|
1022
|
+
addTemporaryClass = function(element, klassOrKlasses) {
|
1023
|
+
addClass(element, klassOrKlasses);
|
1024
|
+
return function() {
|
1025
|
+
return removeClass(element, klassOrKlasses);
|
1026
|
+
};
|
1027
|
+
};
|
1028
|
+
hasClass = function(element, klass) {
|
1029
|
+
var classList;
|
1030
|
+
classList = getElement(element).classList;
|
1031
|
+
return classList.contains(klass);
|
1032
|
+
};
|
966
1033
|
|
967
1034
|
/***
|
968
1035
|
Returns the first [present](/up.util.isPresent) element attribute
|
@@ -975,10 +1042,10 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
975
1042
|
var $element, attrName, attrNames, values;
|
976
1043
|
$element = arguments[0], attrNames = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
977
1044
|
values = (function() {
|
978
|
-
var
|
1045
|
+
var j, len, results;
|
979
1046
|
results = [];
|
980
|
-
for (
|
981
|
-
attrName = attrNames[
|
1047
|
+
for (j = 0, len = attrNames.length; j < len; j++) {
|
1048
|
+
attrName = attrNames[j];
|
982
1049
|
results.push($element.attr(attrName));
|
983
1050
|
}
|
984
1051
|
return results;
|
@@ -1060,8 +1127,9 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
1060
1127
|
scrollbarWidth = memoize(function() {
|
1061
1128
|
var $outer, outer, width;
|
1062
1129
|
$outer = $('<div>');
|
1130
|
+
outer = $outer.get(0);
|
1063
1131
|
$outer.attr('up-viewport', '');
|
1064
|
-
|
1132
|
+
writeInlineStyle(outer, {
|
1065
1133
|
position: 'absolute',
|
1066
1134
|
top: '0',
|
1067
1135
|
left: '0',
|
@@ -1070,7 +1138,6 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
1070
1138
|
overflowY: 'scroll'
|
1071
1139
|
});
|
1072
1140
|
$outer.appendTo(document.body);
|
1073
|
-
outer = $outer.get(0);
|
1074
1141
|
width = outer.offsetWidth - outer.clientWidth;
|
1075
1142
|
$outer.remove();
|
1076
1143
|
return width;
|
@@ -1087,38 +1154,16 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
1087
1154
|
body = document.body;
|
1088
1155
|
$body = $(body);
|
1089
1156
|
html = document.documentElement;
|
1090
|
-
bodyOverflow = $body
|
1157
|
+
bodyOverflow = readComputedStyle($body, 'overflowY');
|
1091
1158
|
forcedScroll = bodyOverflow === 'scroll';
|
1092
1159
|
forcedHidden = bodyOverflow === 'hidden';
|
1093
1160
|
return forcedScroll || (!forcedHidden && html.scrollHeight > html.clientHeight);
|
1094
1161
|
};
|
1095
1162
|
|
1096
|
-
/***
|
1097
|
-
Modifies the given function so it only runs once.
|
1098
|
-
Subsequent calls will return the previous return value.
|
1099
|
-
|
1100
|
-
@function up.util.once
|
1101
|
-
@param {Function} fun
|
1102
|
-
@experimental
|
1103
|
-
*/
|
1104
|
-
once = function(fun) {
|
1105
|
-
var result;
|
1106
|
-
result = void 0;
|
1107
|
-
return function() {
|
1108
|
-
var args;
|
1109
|
-
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|
1110
|
-
if (fun != null) {
|
1111
|
-
result = fun.apply(null, args);
|
1112
|
-
}
|
1113
|
-
fun = void 0;
|
1114
|
-
return result;
|
1115
|
-
};
|
1116
|
-
};
|
1117
|
-
|
1118
1163
|
/***
|
1119
1164
|
Temporarily sets the CSS for the given element.
|
1120
1165
|
|
1121
|
-
@function up.util.
|
1166
|
+
@function up.util.writeTemporaryStyle
|
1122
1167
|
@param {jQuery} $element
|
1123
1168
|
@param {Object} css
|
1124
1169
|
@param {Function} [block]
|
@@ -1128,45 +1173,22 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
1128
1173
|
A function that restores the original CSS when called.
|
1129
1174
|
@internal
|
1130
1175
|
*/
|
1131
|
-
|
1132
|
-
var $element,
|
1176
|
+
writeTemporaryStyle = function(elementOrSelector, newCss, block) {
|
1177
|
+
var $element, oldStyles, restoreOldStyles;
|
1133
1178
|
$element = $(elementOrSelector);
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1137
|
-
return $element.css(oldCss);
|
1179
|
+
oldStyles = readInlineStyle($element, Object.keys(newCss));
|
1180
|
+
restoreOldStyles = function() {
|
1181
|
+
return writeInlineStyle($element, oldStyles);
|
1138
1182
|
};
|
1183
|
+
writeInlineStyle($element, newCss);
|
1139
1184
|
if (block) {
|
1140
1185
|
block();
|
1141
|
-
return
|
1186
|
+
return restoreOldStyles();
|
1142
1187
|
} else {
|
1143
|
-
return
|
1188
|
+
return restoreOldStyles;
|
1144
1189
|
}
|
1145
1190
|
};
|
1146
1191
|
|
1147
|
-
/***
|
1148
|
-
Forces the given jQuery element into an accelerated compositing layer.
|
1149
|
-
|
1150
|
-
@function up.util.forceCompositing
|
1151
|
-
@internal
|
1152
|
-
*/
|
1153
|
-
forceCompositing = function($element) {
|
1154
|
-
var memo, oldTransforms;
|
1155
|
-
oldTransforms = $element.css(['transform', '-webkit-transform']);
|
1156
|
-
if (isBlank(oldTransforms) || oldTransforms['transform'] === 'none') {
|
1157
|
-
memo = function() {
|
1158
|
-
return $element.css(oldTransforms);
|
1159
|
-
};
|
1160
|
-
$element.css({
|
1161
|
-
'transform': 'translateZ(0)',
|
1162
|
-
'-webkit-transform': 'translateZ(0)'
|
1163
|
-
});
|
1164
|
-
} else {
|
1165
|
-
memo = function() {};
|
1166
|
-
}
|
1167
|
-
return memo;
|
1168
|
-
};
|
1169
|
-
|
1170
1192
|
/***
|
1171
1193
|
Forces a repaint of the given element.
|
1172
1194
|
|
@@ -1174,23 +1196,34 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
1174
1196
|
@internal
|
1175
1197
|
*/
|
1176
1198
|
forceRepaint = function(element) {
|
1177
|
-
element =
|
1199
|
+
element = getElement(element);
|
1178
1200
|
return element.offsetHeight;
|
1179
1201
|
};
|
1180
|
-
|
1202
|
+
|
1203
|
+
/**
|
1204
|
+
@function up.util.finishTransition
|
1205
|
+
@internal
|
1206
|
+
*/
|
1207
|
+
concludeCssTransition = function(element) {
|
1208
|
+
var undo;
|
1209
|
+
undo = writeTemporaryStyle(element, {
|
1210
|
+
transition: 'none'
|
1211
|
+
});
|
1212
|
+
forceRepaint(element);
|
1213
|
+
return undo;
|
1214
|
+
};
|
1181
1215
|
|
1182
1216
|
/***
|
1183
1217
|
@internal
|
1184
1218
|
*/
|
1185
1219
|
margins = function(selectorOrElement) {
|
1186
|
-
var
|
1187
|
-
|
1188
|
-
withUnits = $element.css(['margin-top', 'margin-right', 'margin-bottom', 'margin-left']);
|
1220
|
+
var element;
|
1221
|
+
element = getElement(selectorOrElement);
|
1189
1222
|
return {
|
1190
|
-
top:
|
1191
|
-
right:
|
1192
|
-
bottom:
|
1193
|
-
left:
|
1223
|
+
top: readComputedStyleNumber(element, 'marginTop'),
|
1224
|
+
right: readComputedStyleNumber(element, 'marginRight'),
|
1225
|
+
bottom: readComputedStyleNumber(element, 'marginBottom'),
|
1226
|
+
left: readComputedStyleNumber(element, 'marginLeft')
|
1194
1227
|
};
|
1195
1228
|
};
|
1196
1229
|
|
@@ -1254,11 +1287,11 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
1254
1287
|
@internal
|
1255
1288
|
*/
|
1256
1289
|
copyAttributes = function($source, $target) {
|
1257
|
-
var attr,
|
1290
|
+
var attr, j, len, ref, results;
|
1258
1291
|
ref = $source.get(0).attributes;
|
1259
1292
|
results = [];
|
1260
|
-
for (
|
1261
|
-
attr = ref[
|
1293
|
+
for (j = 0, len = ref.length; j < len; j++) {
|
1294
|
+
attr = ref[j];
|
1262
1295
|
if (attr.specified) {
|
1263
1296
|
results.push($target.attr(attr.name, attr.value));
|
1264
1297
|
} else {
|
@@ -1275,7 +1308,13 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
1275
1308
|
@internal
|
1276
1309
|
*/
|
1277
1310
|
selectInSubtree = function($element, selector) {
|
1278
|
-
|
1311
|
+
var $matches;
|
1312
|
+
$matches = $();
|
1313
|
+
if ($element.is(selector)) {
|
1314
|
+
$matches = $matches.add($element);
|
1315
|
+
}
|
1316
|
+
$matches = $matches.add($element.find(selector));
|
1317
|
+
return $matches;
|
1279
1318
|
};
|
1280
1319
|
|
1281
1320
|
/***
|
@@ -1342,12 +1381,12 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
1342
1381
|
@stable
|
1343
1382
|
*/
|
1344
1383
|
only = function() {
|
1345
|
-
var filtered,
|
1384
|
+
var filtered, j, len, object, properties, property;
|
1346
1385
|
object = arguments[0], properties = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
1347
1386
|
filtered = {};
|
1348
|
-
for (
|
1349
|
-
property = properties[
|
1350
|
-
if (object
|
1387
|
+
for (j = 0, len = properties.length; j < len; j++) {
|
1388
|
+
property = properties[j];
|
1389
|
+
if (property in object) {
|
1351
1390
|
filtered[property] = object[property];
|
1352
1391
|
}
|
1353
1392
|
}
|
@@ -1364,11 +1403,11 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
1364
1403
|
@stable
|
1365
1404
|
*/
|
1366
1405
|
except = function() {
|
1367
|
-
var filtered,
|
1406
|
+
var filtered, j, len, object, properties, property;
|
1368
1407
|
object = arguments[0], properties = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
1369
1408
|
filtered = copy(object);
|
1370
|
-
for (
|
1371
|
-
property = properties[
|
1409
|
+
for (j = 0, len = properties.length; j < len; j++) {
|
1410
|
+
property = properties[j];
|
1372
1411
|
delete filtered[property];
|
1373
1412
|
}
|
1374
1413
|
return filtered;
|
@@ -1451,74 +1490,6 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
1451
1490
|
}
|
1452
1491
|
};
|
1453
1492
|
|
1454
|
-
/***
|
1455
|
-
@function up.util.multiSelector
|
1456
|
-
@internal
|
1457
|
-
*/
|
1458
|
-
multiSelector = function(parts) {
|
1459
|
-
var combinedSelector, elements, i, len, obj, part, selectors;
|
1460
|
-
obj = {};
|
1461
|
-
selectors = [];
|
1462
|
-
elements = [];
|
1463
|
-
for (i = 0, len = parts.length; i < len; i++) {
|
1464
|
-
part = parts[i];
|
1465
|
-
if (isString(part)) {
|
1466
|
-
selectors.push(part);
|
1467
|
-
} else {
|
1468
|
-
elements.push(part);
|
1469
|
-
}
|
1470
|
-
}
|
1471
|
-
obj.parsed = elements;
|
1472
|
-
if (selectors.length) {
|
1473
|
-
combinedSelector = selectors.join(', ');
|
1474
|
-
obj.parsed.push(combinedSelector);
|
1475
|
-
}
|
1476
|
-
obj.select = function() {
|
1477
|
-
return obj.find(void 0);
|
1478
|
-
};
|
1479
|
-
obj.find = function($root) {
|
1480
|
-
var $matches, $result, j, len1, ref, selector;
|
1481
|
-
$result = nullJQuery();
|
1482
|
-
ref = obj.parsed;
|
1483
|
-
for (j = 0, len1 = ref.length; j < len1; j++) {
|
1484
|
-
selector = ref[j];
|
1485
|
-
$matches = $root ? $root.find(selector) : $(selector);
|
1486
|
-
$result = $result.add($matches);
|
1487
|
-
}
|
1488
|
-
return $result;
|
1489
|
-
};
|
1490
|
-
obj.selectInSubtree = function($start) {
|
1491
|
-
var $matches;
|
1492
|
-
$matches = obj.find($start);
|
1493
|
-
if (obj.doesMatch($start)) {
|
1494
|
-
$matches = $matches.add($start);
|
1495
|
-
}
|
1496
|
-
return $matches;
|
1497
|
-
};
|
1498
|
-
obj.doesMatch = function(element) {
|
1499
|
-
var $element;
|
1500
|
-
$element = $(element);
|
1501
|
-
return any(obj.parsed, function(selector) {
|
1502
|
-
return $element.is(selector);
|
1503
|
-
});
|
1504
|
-
};
|
1505
|
-
obj.seekUp = function(start) {
|
1506
|
-
var $element, $result, $start;
|
1507
|
-
$start = $(start);
|
1508
|
-
$element = $start;
|
1509
|
-
$result = void 0;
|
1510
|
-
while ($element.length) {
|
1511
|
-
if (obj.doesMatch($element)) {
|
1512
|
-
$result = $element;
|
1513
|
-
break;
|
1514
|
-
}
|
1515
|
-
$element = $element.parent();
|
1516
|
-
}
|
1517
|
-
return $result || nullJQuery();
|
1518
|
-
};
|
1519
|
-
return obj;
|
1520
|
-
};
|
1521
|
-
|
1522
1493
|
/***
|
1523
1494
|
If the given `value` is a function, calls the function with the given `args`.
|
1524
1495
|
Otherwise it just returns `value`.
|
@@ -1580,7 +1551,7 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
1580
1551
|
*/
|
1581
1552
|
unwrapElement = function(wrapper) {
|
1582
1553
|
var parent, wrappedNodes;
|
1583
|
-
wrapper =
|
1554
|
+
wrapper = getElement(wrapper);
|
1584
1555
|
parent = wrapper.parentNode;
|
1585
1556
|
wrappedNodes = toArray(wrapper.childNodes);
|
1586
1557
|
each(wrappedNodes, function(wrappedNode) {
|
@@ -1597,7 +1568,7 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
1597
1568
|
var $match, position;
|
1598
1569
|
$match = void 0;
|
1599
1570
|
while (($element = $element.parent()) && $element.length) {
|
1600
|
-
position = $element
|
1571
|
+
position = readComputedStyle($element, 'position');
|
1601
1572
|
if (position === 'absolute' || position === 'relative' || $element.is('body')) {
|
1602
1573
|
$match = $element;
|
1603
1574
|
break;
|
@@ -1616,7 +1587,7 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
1616
1587
|
var $element, position;
|
1617
1588
|
$element = $(element);
|
1618
1589
|
while (true) {
|
1619
|
-
position = $element
|
1590
|
+
position = readComputedStyle($element, 'position');
|
1620
1591
|
if (position === 'fixed') {
|
1621
1592
|
return true;
|
1622
1593
|
} else {
|
@@ -1638,7 +1609,7 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
1638
1609
|
$futureOffsetParent = offsetParent($element);
|
1639
1610
|
elementCoords = $element.position();
|
1640
1611
|
futureParentCoords = $futureOffsetParent.offset();
|
1641
|
-
return $element
|
1612
|
+
return writeInlineStyle($element, {
|
1642
1613
|
position: 'absolute',
|
1643
1614
|
left: elementCoords.left - futureParentCoords.left,
|
1644
1615
|
top: elementCoords.top - futureParentCoords.top + $viewport.scrollTop(),
|
@@ -1656,7 +1627,7 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
1656
1627
|
@internal
|
1657
1628
|
*/
|
1658
1629
|
requestDataAsArray = function(data) {
|
1659
|
-
var array,
|
1630
|
+
var array, j, len, pair, part, query, ref;
|
1660
1631
|
if (isArray(data)) {
|
1661
1632
|
data;
|
1662
1633
|
}
|
@@ -1666,8 +1637,8 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
1666
1637
|
query = requestDataAsQuery(data);
|
1667
1638
|
array = [];
|
1668
1639
|
ref = query.split('&');
|
1669
|
-
for (
|
1670
|
-
part = ref[
|
1640
|
+
for (j = 0, len = ref.length; j < len; j++) {
|
1641
|
+
part = ref[j];
|
1671
1642
|
if (isPresent(part)) {
|
1672
1643
|
pair = part.split('=');
|
1673
1644
|
array.push({
|
@@ -1883,14 +1854,87 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
1883
1854
|
return {};
|
1884
1855
|
}
|
1885
1856
|
};
|
1886
|
-
|
1887
|
-
|
1888
|
-
|
1889
|
-
|
1890
|
-
|
1891
|
-
|
1892
|
-
|
1857
|
+
CASE_CONVERSION_GROUP = /[^\-\_]+?(?=[A-Z\-\_]|$)/g;
|
1858
|
+
convertCase = function(string, separator, fn) {
|
1859
|
+
var parts;
|
1860
|
+
parts = string.match(CASE_CONVERSION_GROUP);
|
1861
|
+
parts = map(parts, fn);
|
1862
|
+
return parts.join(separator);
|
1863
|
+
};
|
1864
|
+
|
1865
|
+
/***
|
1866
|
+
Returns a copy of the given string that is transformed to `kebab-case`.
|
1867
|
+
|
1868
|
+
@function up.util.kebabCase
|
1869
|
+
@param {string} string
|
1870
|
+
@return {string}
|
1871
|
+
@internal
|
1872
|
+
*/
|
1873
|
+
kebabCase = function(string) {
|
1874
|
+
return convertCase(string, '-', function(part) {
|
1875
|
+
return part.toLowerCase();
|
1876
|
+
});
|
1877
|
+
};
|
1878
|
+
|
1879
|
+
/***
|
1880
|
+
Returns a copy of the given string that is transformed to `camelCase`.
|
1881
|
+
|
1882
|
+
@function up.util.camelCase
|
1883
|
+
@param {string} string
|
1884
|
+
@return {string}
|
1885
|
+
@internal
|
1886
|
+
*/
|
1887
|
+
camelCase = function(string) {
|
1888
|
+
return convertCase(string, '', function(part, i) {
|
1889
|
+
if (i === 0) {
|
1890
|
+
return part.toLowerCase();
|
1891
|
+
} else {
|
1892
|
+
return part.charAt(0).toUpperCase() + part.substr(1).toLowerCase();
|
1893
|
+
}
|
1894
|
+
});
|
1895
|
+
};
|
1896
|
+
|
1897
|
+
/***
|
1898
|
+
Returns a copy of the given object with all keys renamed
|
1899
|
+
in `kebab-case`.
|
1900
|
+
|
1901
|
+
Does not change the given object.
|
1902
|
+
|
1903
|
+
@function up.util.kebabCaseKeys
|
1904
|
+
@param {object} obj
|
1905
|
+
@return {object}
|
1906
|
+
@internal
|
1907
|
+
*/
|
1908
|
+
kebabCaseKeys = function(obj) {
|
1909
|
+
return copyWithRenamedKeys(obj, kebabCase);
|
1910
|
+
};
|
1911
|
+
|
1912
|
+
/***
|
1913
|
+
Returns a copy of the given object with all keys renamed
|
1914
|
+
in `camelCase`.
|
1915
|
+
|
1916
|
+
Does not change the given object.
|
1917
|
+
|
1918
|
+
@function up.util.camelCaseKeys
|
1919
|
+
@param {object} obj
|
1920
|
+
@return {object}
|
1921
|
+
@internal
|
1922
|
+
*/
|
1923
|
+
camelCaseKeys = function(obj) {
|
1924
|
+
return copyWithRenamedKeys(obj, camelCase);
|
1925
|
+
};
|
1926
|
+
copyWithRenamedKeys = function(obj, keyTransformer) {
|
1927
|
+
var k, result, v;
|
1928
|
+
result = {};
|
1929
|
+
for (k in obj) {
|
1930
|
+
v = obj[k];
|
1931
|
+
k = keyTransformer(k);
|
1932
|
+
result[k] = v;
|
1893
1933
|
}
|
1934
|
+
return result;
|
1935
|
+
};
|
1936
|
+
opacity = function(element) {
|
1937
|
+
return readComputedStyleNumber(element, 'opacity');
|
1894
1938
|
};
|
1895
1939
|
whenReady = memoize(function() {
|
1896
1940
|
if ($.isReady) {
|
@@ -1913,7 +1957,7 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
1913
1957
|
@internal
|
1914
1958
|
*/
|
1915
1959
|
isDetached = function(element) {
|
1916
|
-
element =
|
1960
|
+
element = getElement(element);
|
1917
1961
|
return !$.contains(document.documentElement, element);
|
1918
1962
|
};
|
1919
1963
|
|
@@ -2094,6 +2138,147 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
2094
2138
|
return $old;
|
2095
2139
|
};
|
2096
2140
|
|
2141
|
+
/***
|
2142
|
+
Hides the given element faster than `jQuery.fn.hide()`.
|
2143
|
+
|
2144
|
+
@function up.util.hide
|
2145
|
+
@param {jQuery|Element} element
|
2146
|
+
*/
|
2147
|
+
hide = function(element) {
|
2148
|
+
return writeInlineStyle(element, {
|
2149
|
+
display: 'none'
|
2150
|
+
});
|
2151
|
+
};
|
2152
|
+
|
2153
|
+
/***
|
2154
|
+
Gets the computed style(s) for the given element.
|
2155
|
+
|
2156
|
+
@function up.util.readComputedStyle
|
2157
|
+
@param {jQuery|Element} element
|
2158
|
+
@param {String|Array} propOrProps
|
2159
|
+
One or more CSS property names in camelCase.
|
2160
|
+
@return {string|object}
|
2161
|
+
@internal
|
2162
|
+
*/
|
2163
|
+
readComputedStyle = function(element, props) {
|
2164
|
+
var style;
|
2165
|
+
element = getElement(element);
|
2166
|
+
style = window.getComputedStyle(element);
|
2167
|
+
return extractFromStyleObject(style, props);
|
2168
|
+
};
|
2169
|
+
|
2170
|
+
/***
|
2171
|
+
Gets a computed style value for the given element.
|
2172
|
+
If a value is set, the value is parsed to a number before returning.
|
2173
|
+
|
2174
|
+
@function up.util.readComputedStyleNumber
|
2175
|
+
@param {jQuery|Element} element
|
2176
|
+
@param {String} prop
|
2177
|
+
A CSS property name in camelCase.
|
2178
|
+
@return {string|object}
|
2179
|
+
@internal
|
2180
|
+
*/
|
2181
|
+
readComputedStyleNumber = function(element, prop) {
|
2182
|
+
var rawValue;
|
2183
|
+
rawValue = readComputedStyle(element, prop);
|
2184
|
+
if (isGiven(rawValue)) {
|
2185
|
+
return parseFloat(rawValue);
|
2186
|
+
} else {
|
2187
|
+
return void 0;
|
2188
|
+
}
|
2189
|
+
};
|
2190
|
+
|
2191
|
+
/***
|
2192
|
+
Gets the given inline style(s) from the given element's `[style]` attribute.
|
2193
|
+
|
2194
|
+
@function up.util.readInlineStyle
|
2195
|
+
@param {jQuery|Element} element
|
2196
|
+
@param {String|Array} propOrProps
|
2197
|
+
One or more CSS property names in camelCase.
|
2198
|
+
@return {string|object}
|
2199
|
+
@internal
|
2200
|
+
*/
|
2201
|
+
readInlineStyle = function(element, props) {
|
2202
|
+
var style;
|
2203
|
+
element = getElement(element);
|
2204
|
+
style = element.style;
|
2205
|
+
return extractFromStyleObject(style, props);
|
2206
|
+
};
|
2207
|
+
extractFromStyleObject = function(style, keyOrKeys) {
|
2208
|
+
if (isString(keyOrKeys)) {
|
2209
|
+
return style[keyOrKeys];
|
2210
|
+
} else {
|
2211
|
+
return only.apply(null, [style].concat(slice.call(keyOrKeys)));
|
2212
|
+
}
|
2213
|
+
};
|
2214
|
+
|
2215
|
+
/***
|
2216
|
+
Merges the given inline style(s) into the given element's `[style]` attribute.
|
2217
|
+
|
2218
|
+
@function up.util.readInlineStyle
|
2219
|
+
@param {jQuery|Element} element
|
2220
|
+
@param {Object} props
|
2221
|
+
One or more CSS properties with camelCase keys.
|
2222
|
+
@return {string|object}
|
2223
|
+
@internal
|
2224
|
+
*/
|
2225
|
+
writeInlineStyle = function(element, props) {
|
2226
|
+
var key, results, style, value;
|
2227
|
+
element = getElement(element);
|
2228
|
+
style = element.style;
|
2229
|
+
results = [];
|
2230
|
+
for (key in props) {
|
2231
|
+
value = props[key];
|
2232
|
+
value = normalizeStyleValueForWrite(key, value);
|
2233
|
+
results.push(style[key] = value);
|
2234
|
+
}
|
2235
|
+
return results;
|
2236
|
+
};
|
2237
|
+
normalizeStyleValueForWrite = function(key, value) {
|
2238
|
+
if (isMissing(value)) {
|
2239
|
+
value = '';
|
2240
|
+
} else if (CSS_LENGTH_PROPS.has(key)) {
|
2241
|
+
value = cssLength(value);
|
2242
|
+
}
|
2243
|
+
return value;
|
2244
|
+
};
|
2245
|
+
CSS_LENGTH_PROPS = arrayToSet(['top', 'right', 'bottom', 'left', 'padding', 'paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft', 'margin', 'marginTop', 'marginRight', 'marginBottom', 'marginLeft', 'width', 'height', 'maxWidth', 'maxHeight', 'minWidth', 'minHeight']);
|
2246
|
+
|
2247
|
+
/**
|
2248
|
+
Converts the given value to a CSS length value, adding a `px` unit if required.
|
2249
|
+
|
2250
|
+
@function up.util.cssLength
|
2251
|
+
@internal
|
2252
|
+
*/
|
2253
|
+
cssLength = function(obj) {
|
2254
|
+
if (isNumber(obj) || (isString(obj) && /^\d+$/.test(obj))) {
|
2255
|
+
return obj.toString() + "px";
|
2256
|
+
} else {
|
2257
|
+
return obj;
|
2258
|
+
}
|
2259
|
+
};
|
2260
|
+
|
2261
|
+
/**
|
2262
|
+
Returns whether the given element has a CSS transition set.
|
2263
|
+
|
2264
|
+
@function up.util.hasCssTransition
|
2265
|
+
@return {boolean}
|
2266
|
+
@internal
|
2267
|
+
*/
|
2268
|
+
hasCssTransition = function(elementOrStyleHash) {
|
2269
|
+
var duration, element, noTransition, prop, style;
|
2270
|
+
if (isOptions(elementOrStyleHash)) {
|
2271
|
+
style = elementOrStyleHash;
|
2272
|
+
} else {
|
2273
|
+
element = getElement(element);
|
2274
|
+
style = getComputedStyle(element);
|
2275
|
+
}
|
2276
|
+
prop = style.transitionProperty;
|
2277
|
+
duration = style.transitionDuration;
|
2278
|
+
noTransition = prop === 'none' || (prop === 'all' && duration === 0);
|
2279
|
+
return !noTransition;
|
2280
|
+
};
|
2281
|
+
|
2097
2282
|
/***
|
2098
2283
|
Flattens the given `array` a single level deep.
|
2099
2284
|
|
@@ -2105,10 +2290,10 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
2105
2290
|
@internal
|
2106
2291
|
*/
|
2107
2292
|
flatten = function(array) {
|
2108
|
-
var flattened,
|
2293
|
+
var flattened, j, len, object;
|
2109
2294
|
flattened = [];
|
2110
|
-
for (
|
2111
|
-
object = array[
|
2295
|
+
for (j = 0, len = array.length; j < len; j++) {
|
2296
|
+
object = array[j];
|
2112
2297
|
if (isArray(object)) {
|
2113
2298
|
flattened = flattened.concat(object);
|
2114
2299
|
} else {
|
@@ -2207,6 +2392,19 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
2207
2392
|
isBodyDescendant = function(element) {
|
2208
2393
|
return $(element).parents('body').length > 0;
|
2209
2394
|
};
|
2395
|
+
isEqual = function(a, b) {
|
2396
|
+
if (typeof a !== typeof b) {
|
2397
|
+
return false;
|
2398
|
+
} else if (isArray(a)) {
|
2399
|
+
return a.length === b.length && all(a, function(elem, index) {
|
2400
|
+
return isEqual(elem, b[index]);
|
2401
|
+
});
|
2402
|
+
} else if (isObject(a)) {
|
2403
|
+
return fail('isEqual cannot compare objects yet');
|
2404
|
+
} else {
|
2405
|
+
return a === b;
|
2406
|
+
}
|
2407
|
+
};
|
2210
2408
|
return {
|
2211
2409
|
requestDataAsArray: requestDataAsArray,
|
2212
2410
|
requestDataAsQuery: requestDataAsQuery,
|
@@ -2266,14 +2464,17 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
2266
2464
|
isUnmodifiedKeyEvent: isUnmodifiedKeyEvent,
|
2267
2465
|
isUnmodifiedMouseEvent: isUnmodifiedMouseEvent,
|
2268
2466
|
nullJQuery: nullJQuery,
|
2269
|
-
|
2467
|
+
element: getElement,
|
2270
2468
|
setTimer: setTimer,
|
2271
2469
|
nextFrame: nextFrame,
|
2272
2470
|
measure: measure,
|
2273
|
-
|
2274
|
-
|
2275
|
-
|
2471
|
+
addClass: addClass,
|
2472
|
+
removeClass: removeClass,
|
2473
|
+
hasClass: hasClass,
|
2474
|
+
addTemporaryClass: addTemporaryClass,
|
2475
|
+
writeTemporaryStyle: writeTemporaryStyle,
|
2276
2476
|
forceRepaint: forceRepaint,
|
2477
|
+
concludeCssTransition: concludeCssTransition,
|
2277
2478
|
escapePressed: escapePressed,
|
2278
2479
|
copyAttributes: copyAttributes,
|
2279
2480
|
selectInSubtree: selectInSubtree,
|
@@ -2294,7 +2495,10 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
2294
2495
|
config: config,
|
2295
2496
|
openConfig: openConfig,
|
2296
2497
|
unwrapElement: unwrapElement,
|
2297
|
-
|
2498
|
+
camelCase: camelCase,
|
2499
|
+
camelCaseKeys: camelCaseKeys,
|
2500
|
+
kebabCase: kebabCase,
|
2501
|
+
kebabCaseKeys: kebabCaseKeys,
|
2298
2502
|
error: fail,
|
2299
2503
|
pluckData: pluckData,
|
2300
2504
|
pluckKey: pluckKey,
|
@@ -2302,6 +2506,7 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
2302
2506
|
extractOptions: extractOptions,
|
2303
2507
|
isDetached: isDetached,
|
2304
2508
|
noop: noop,
|
2509
|
+
asyncNoop: asyncNoop,
|
2305
2510
|
opacity: opacity,
|
2306
2511
|
whenReady: whenReady,
|
2307
2512
|
identity: identity,
|
@@ -2322,7 +2527,15 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
2322
2527
|
rejectOnError: rejectOnError,
|
2323
2528
|
isBodyDescendant: isBodyDescendant,
|
2324
2529
|
isCrossDomain: isCrossDomain,
|
2325
|
-
microtask: microtask
|
2530
|
+
microtask: microtask,
|
2531
|
+
isEqual: isEqual,
|
2532
|
+
hide: hide,
|
2533
|
+
cssLength: cssLength,
|
2534
|
+
readComputedStyle: readComputedStyle,
|
2535
|
+
readComputedStyleNumber: readComputedStyleNumber,
|
2536
|
+
readInlineStyle: readInlineStyle,
|
2537
|
+
writeInlineStyle: writeInlineStyle,
|
2538
|
+
hasCssTransition: hasCssTransition
|
2326
2539
|
};
|
2327
2540
|
})(jQuery);
|
2328
2541
|
|
@@ -2527,6 +2740,159 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
2527
2740
|
|
2528
2741
|
})();
|
2529
2742
|
|
2743
|
+
}).call(this);
|
2744
|
+
(function() {
|
2745
|
+
var u,
|
2746
|
+
bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
|
2747
|
+
|
2748
|
+
u = up.util;
|
2749
|
+
|
2750
|
+
up.CssTransition = (function() {
|
2751
|
+
function CssTransition($element, lastFrame, options) {
|
2752
|
+
this.startMotion = bind(this.startMotion, this);
|
2753
|
+
this.resumeOldTransition = bind(this.resumeOldTransition, this);
|
2754
|
+
this.pauseOldTransition = bind(this.pauseOldTransition, this);
|
2755
|
+
this.finish = bind(this.finish, this);
|
2756
|
+
this.onTransitionEnd = bind(this.onTransitionEnd, this);
|
2757
|
+
this.stopListenToTransitionEnd = bind(this.stopListenToTransitionEnd, this);
|
2758
|
+
this.listenToTransitionEnd = bind(this.listenToTransitionEnd, this);
|
2759
|
+
this.stopFallbackTimer = bind(this.stopFallbackTimer, this);
|
2760
|
+
this.startFallbackTimer = bind(this.startFallbackTimer, this);
|
2761
|
+
this.onFinishEvent = bind(this.onFinishEvent, this);
|
2762
|
+
this.stopListenToFinishEvent = bind(this.stopListenToFinishEvent, this);
|
2763
|
+
this.listenToFinishEvent = bind(this.listenToFinishEvent, this);
|
2764
|
+
this.start = bind(this.start, this);
|
2765
|
+
this.$element = $element;
|
2766
|
+
this.element = u.element($element);
|
2767
|
+
this.lastFrameCamel = u.camelCaseKeys(lastFrame);
|
2768
|
+
this.lastFrameKebab = u.kebabCaseKeys(lastFrame);
|
2769
|
+
this.lastFrameKeysKebab = Object.keys(this.lastFrameKebab);
|
2770
|
+
this.finishEvent = options.finishEvent;
|
2771
|
+
this.duration = options.duration;
|
2772
|
+
this.delay = options.delay;
|
2773
|
+
this.totalDuration = this.delay + this.duration;
|
2774
|
+
this.easing = options.easing;
|
2775
|
+
this.finished = false;
|
2776
|
+
}
|
2777
|
+
|
2778
|
+
CssTransition.prototype.start = function() {
|
2779
|
+
if (this.lastFrameKeysKebab.length === 0) {
|
2780
|
+
this.finished = true;
|
2781
|
+
return Promise.resolve();
|
2782
|
+
}
|
2783
|
+
this.deferred = u.newDeferred();
|
2784
|
+
this.pauseOldTransition();
|
2785
|
+
this.startTime = new Date();
|
2786
|
+
this.startFallbackTimer();
|
2787
|
+
this.listenToFinishEvent();
|
2788
|
+
this.listenToTransitionEnd();
|
2789
|
+
this.startMotion();
|
2790
|
+
return this.deferred.promise();
|
2791
|
+
};
|
2792
|
+
|
2793
|
+
CssTransition.prototype.listenToFinishEvent = function() {
|
2794
|
+
if (this.finishEvent) {
|
2795
|
+
return this.$element.on(this.finishEvent, this.onFinishEvent);
|
2796
|
+
}
|
2797
|
+
};
|
2798
|
+
|
2799
|
+
CssTransition.prototype.stopListenToFinishEvent = function() {
|
2800
|
+
if (this.finishEvent) {
|
2801
|
+
return this.$element.off(this.finishEvent, this.onFinishEvent);
|
2802
|
+
}
|
2803
|
+
};
|
2804
|
+
|
2805
|
+
CssTransition.prototype.onFinishEvent = function(event) {
|
2806
|
+
event.stopPropagation();
|
2807
|
+
return this.finish();
|
2808
|
+
};
|
2809
|
+
|
2810
|
+
CssTransition.prototype.startFallbackTimer = function() {
|
2811
|
+
var timingTolerance;
|
2812
|
+
timingTolerance = 100;
|
2813
|
+
return this.fallbackTimer = u.setTimer(this.totalDuration + timingTolerance, (function(_this) {
|
2814
|
+
return function() {
|
2815
|
+
return _this.finish();
|
2816
|
+
};
|
2817
|
+
})(this));
|
2818
|
+
};
|
2819
|
+
|
2820
|
+
CssTransition.prototype.stopFallbackTimer = function() {
|
2821
|
+
return clearTimeout(this.fallbackTimer);
|
2822
|
+
};
|
2823
|
+
|
2824
|
+
CssTransition.prototype.listenToTransitionEnd = function() {
|
2825
|
+
return this.$element.on('transitionend', this.onTransitionEnd);
|
2826
|
+
};
|
2827
|
+
|
2828
|
+
CssTransition.prototype.stopListenToTransitionEnd = function() {
|
2829
|
+
return this.$element.off('transitionend', this.onTransitionEnd);
|
2830
|
+
};
|
2831
|
+
|
2832
|
+
CssTransition.prototype.onTransitionEnd = function(event) {
|
2833
|
+
var completedPropertyKebab, elapsed;
|
2834
|
+
if (event.target !== this.element) {
|
2835
|
+
return;
|
2836
|
+
}
|
2837
|
+
elapsed = new Date() - this.startTime;
|
2838
|
+
if (!(elapsed > 0.25 * this.totalDuration)) {
|
2839
|
+
return;
|
2840
|
+
}
|
2841
|
+
completedPropertyKebab = event.originalEvent.propertyName;
|
2842
|
+
if (!u.contains(this.lastFrameKeysKebab, completedPropertyKebab)) {
|
2843
|
+
return;
|
2844
|
+
}
|
2845
|
+
return this.finish();
|
2846
|
+
};
|
2847
|
+
|
2848
|
+
CssTransition.prototype.finish = function() {
|
2849
|
+
if (this.finished) {
|
2850
|
+
return;
|
2851
|
+
}
|
2852
|
+
this.finished = true;
|
2853
|
+
this.stopFallbackTimer();
|
2854
|
+
this.stopListenToFinishEvent();
|
2855
|
+
this.stopListenToTransitionEnd();
|
2856
|
+
u.concludeCssTransition(this.element);
|
2857
|
+
this.resumeOldTransition();
|
2858
|
+
return this.deferred.resolve();
|
2859
|
+
};
|
2860
|
+
|
2861
|
+
CssTransition.prototype.pauseOldTransition = function() {
|
2862
|
+
var oldTransition, oldTransitionFrameCamel, oldTransitionFrameKebab, oldTransitionProperties;
|
2863
|
+
oldTransition = u.readComputedStyle(this.element, ['transitionProperty', 'transitionDuration', 'transitionDelay', 'transitionTimingFunction']);
|
2864
|
+
if (u.hasCssTransition(oldTransition)) {
|
2865
|
+
if (oldTransition.transitionProperty !== 'all') {
|
2866
|
+
oldTransitionProperties = oldTransition.transitionProperty.split(/\s*,\s*/);
|
2867
|
+
oldTransitionFrameKebab = u.readComputedStyle(this.element, oldTransitionProperties);
|
2868
|
+
oldTransitionFrameCamel = u.camelCaseKeys(oldTransitionFrameKebab);
|
2869
|
+
this.setOldTransitionTargetFrame = u.writeTemporaryStyle(this.element, oldTransitionFrameCamel);
|
2870
|
+
}
|
2871
|
+
return this.setOldTransition = u.concludeCssTransition(this.element);
|
2872
|
+
}
|
2873
|
+
};
|
2874
|
+
|
2875
|
+
CssTransition.prototype.resumeOldTransition = function() {
|
2876
|
+
if (typeof this.setOldTransitionTargetFrame === "function") {
|
2877
|
+
this.setOldTransitionTargetFrame();
|
2878
|
+
}
|
2879
|
+
return typeof this.setOldTransition === "function" ? this.setOldTransition() : void 0;
|
2880
|
+
};
|
2881
|
+
|
2882
|
+
CssTransition.prototype.startMotion = function() {
|
2883
|
+
u.writeInlineStyle(this.element, {
|
2884
|
+
transitionProperty: Object.keys(this.lastFrameKebab).join(', '),
|
2885
|
+
transitionDuration: this.duration + "ms",
|
2886
|
+
transitionDelay: this.delay + "ms",
|
2887
|
+
transitionTimingFunction: this.easing
|
2888
|
+
});
|
2889
|
+
return u.writeInlineStyle(this.element, this.lastFrameCamel);
|
2890
|
+
};
|
2891
|
+
|
2892
|
+
return CssTransition;
|
2893
|
+
|
2894
|
+
})();
|
2895
|
+
|
2530
2896
|
}).call(this);
|
2531
2897
|
(function() {
|
2532
2898
|
var u,
|
@@ -2787,7 +3153,7 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
2787
3153
|
var $hungries, $hungry, $newHungry, hungry, hungrySteps, j, len, selector, transition;
|
2788
3154
|
hungrySteps = [];
|
2789
3155
|
if (this.hungry) {
|
2790
|
-
$hungries = up.radio.hungrySelector()
|
3156
|
+
$hungries = $(up.radio.hungrySelector());
|
2791
3157
|
transition = u.option(up.radio.config.hungryTransition, this.transition);
|
2792
3158
|
for (j = 0, len = $hungries.length; j < len; j++) {
|
2793
3159
|
hungry = $hungries[j];
|
@@ -3031,64 +3397,65 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
3031
3397
|
|
3032
3398
|
up.MotionTracker = (function() {
|
3033
3399
|
function MotionTracker(name) {
|
3400
|
+
this.reset = bind(this.reset, this);
|
3401
|
+
this.whileForwardingFinishEvent = bind(this.whileForwardingFinishEvent, this);
|
3034
3402
|
this.forwardFinishEvent = bind(this.forwardFinishEvent, this);
|
3035
|
-
this.
|
3036
|
-
this.
|
3403
|
+
this.unmarkCluster = bind(this.unmarkCluster, this);
|
3404
|
+
this.markCluster = bind(this.markCluster, this);
|
3037
3405
|
this.whenElementFinished = bind(this.whenElementFinished, this);
|
3406
|
+
this.emitFinishEvent = bind(this.emitFinishEvent, this);
|
3038
3407
|
this.finishOneElement = bind(this.finishOneElement, this);
|
3408
|
+
this.isActive = bind(this.isActive, this);
|
3409
|
+
this.expandFinishRequest = bind(this.expandFinishRequest, this);
|
3039
3410
|
this.finish = bind(this.finish, this);
|
3040
3411
|
this.claim = bind(this.claim, this);
|
3041
|
-
this.
|
3412
|
+
this.activeClass = "up-" + name;
|
3042
3413
|
this.dataKey = "up-" + name + "-finished";
|
3043
|
-
this.selector = "." + this.
|
3414
|
+
this.selector = "." + this.activeClass;
|
3044
3415
|
this.finishEvent = "up:" + name + ":finish";
|
3416
|
+
this.finishCount = 0;
|
3417
|
+
this.clusterCount = 0;
|
3045
3418
|
}
|
3046
3419
|
|
3047
3420
|
|
3048
3421
|
/***
|
3049
|
-
Finishes all animations in the given element's ancestors and descendants,
|
3422
|
+
Finishes all animations in the given element cluster's ancestors and descendants,
|
3050
3423
|
then calls the animator.
|
3051
3424
|
|
3052
|
-
@method claim
|
3053
|
-
@param {jQuery} $element
|
3054
|
-
@param {Function(jQuery): Promise} animator
|
3055
|
-
@return {Promise} A promise that is fulfilled when the new animation ends.
|
3056
|
-
*/
|
3057
|
-
|
3058
|
-
MotionTracker.prototype.claim = function($element, animator) {
|
3059
|
-
return this.finish($element).then((function(_this) {
|
3060
|
-
return function() {
|
3061
|
-
return _this.start($element, animator);
|
3062
|
-
};
|
3063
|
-
})(this));
|
3064
|
-
};
|
3065
|
-
|
3066
|
-
|
3067
|
-
/***
|
3068
|
-
Calls the given animator to animate the given element.
|
3069
|
-
|
3070
3425
|
The animation returned by the animator is tracked so it can be
|
3071
3426
|
[`finished`](/up.MotionTracker.finish) later.
|
3072
3427
|
|
3073
|
-
No animations are finished before starting the new animation.
|
3074
|
-
Use [`claim()`](/up.MotionTracker.claim) for that.
|
3075
|
-
|
3076
3428
|
@method claim
|
3077
|
-
@param {jQuery} $
|
3429
|
+
@param {jQuery} $cluster
|
3078
3430
|
@param {Function(jQuery): Promise} animator
|
3431
|
+
@param {Object} memory.trackMotion = true
|
3432
|
+
Whether
|
3079
3433
|
@return {Promise} A promise that is fulfilled when the new animation ends.
|
3080
3434
|
*/
|
3081
3435
|
|
3082
|
-
MotionTracker.prototype.
|
3083
|
-
var
|
3084
|
-
|
3085
|
-
|
3086
|
-
|
3087
|
-
|
3088
|
-
|
3089
|
-
|
3090
|
-
|
3091
|
-
|
3436
|
+
MotionTracker.prototype.claim = function(cluster, animator, memory) {
|
3437
|
+
var $cluster;
|
3438
|
+
if (memory == null) {
|
3439
|
+
memory = {};
|
3440
|
+
}
|
3441
|
+
$cluster = $(cluster);
|
3442
|
+
memory.trackMotion = u.option(memory.trackMotion, up.motion.isEnabled());
|
3443
|
+
if (memory.trackMotion === false) {
|
3444
|
+
return u.microtask(animator);
|
3445
|
+
} else {
|
3446
|
+
memory.trackMotion = false;
|
3447
|
+
return this.finish($cluster).then((function(_this) {
|
3448
|
+
return function() {
|
3449
|
+
var promise;
|
3450
|
+
promise = _this.whileForwardingFinishEvent($cluster, animator);
|
3451
|
+
promise = promise.then(function() {
|
3452
|
+
return _this.unmarkCluster($cluster);
|
3453
|
+
});
|
3454
|
+
_this.markCluster($cluster, promise);
|
3455
|
+
return promise;
|
3456
|
+
};
|
3457
|
+
})(this));
|
3458
|
+
}
|
3092
3459
|
};
|
3093
3460
|
|
3094
3461
|
|
@@ -3102,6 +3469,10 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
3102
3469
|
|
3103
3470
|
MotionTracker.prototype.finish = function(elements) {
|
3104
3471
|
var $elements, allFinished;
|
3472
|
+
this.finishCount++;
|
3473
|
+
if (this.clusterCount === 0 || !up.motion.isEnabled()) {
|
3474
|
+
return Promise.resolve();
|
3475
|
+
}
|
3105
3476
|
$elements = this.expandFinishRequest(elements);
|
3106
3477
|
allFinished = u.map($elements, this.finishOneElement);
|
3107
3478
|
return Promise.all(allFinished);
|
@@ -3115,25 +3486,42 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
3115
3486
|
}
|
3116
3487
|
};
|
3117
3488
|
|
3489
|
+
MotionTracker.prototype.isActive = function(element) {
|
3490
|
+
return u.hasClass(element, this.activeClass);
|
3491
|
+
};
|
3492
|
+
|
3118
3493
|
MotionTracker.prototype.finishOneElement = function(element) {
|
3119
3494
|
var $element;
|
3120
3495
|
$element = $(element);
|
3121
|
-
$element
|
3496
|
+
this.emitFinishEvent($element);
|
3122
3497
|
return this.whenElementFinished($element);
|
3123
3498
|
};
|
3124
3499
|
|
3500
|
+
MotionTracker.prototype.emitFinishEvent = function($element, eventAttrs) {
|
3501
|
+
if (eventAttrs == null) {
|
3502
|
+
eventAttrs = {};
|
3503
|
+
}
|
3504
|
+
eventAttrs = u.merge({
|
3505
|
+
$element: $element,
|
3506
|
+
message: false
|
3507
|
+
}, eventAttrs);
|
3508
|
+
return up.emit(this.finishEvent, eventAttrs);
|
3509
|
+
};
|
3510
|
+
|
3125
3511
|
MotionTracker.prototype.whenElementFinished = function($element) {
|
3126
3512
|
return $element.data(this.dataKey) || Promise.resolve();
|
3127
3513
|
};
|
3128
3514
|
|
3129
|
-
MotionTracker.prototype.
|
3130
|
-
|
3131
|
-
|
3515
|
+
MotionTracker.prototype.markCluster = function($cluster, promise) {
|
3516
|
+
this.clusterCount++;
|
3517
|
+
$cluster.addClass(this.activeClass);
|
3518
|
+
return $cluster.data(this.dataKey, promise);
|
3132
3519
|
};
|
3133
3520
|
|
3134
|
-
MotionTracker.prototype.
|
3135
|
-
|
3136
|
-
|
3521
|
+
MotionTracker.prototype.unmarkCluster = function($cluster) {
|
3522
|
+
this.clusterCount--;
|
3523
|
+
$cluster.removeClass(this.activeClass);
|
3524
|
+
return $cluster.removeData(this.dataKey);
|
3137
3525
|
};
|
3138
3526
|
|
3139
3527
|
MotionTracker.prototype.forwardFinishEvent = function($original, $ghost, duration) {
|
@@ -3151,6 +3539,43 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
3151
3539
|
})(this));
|
3152
3540
|
};
|
3153
3541
|
|
3542
|
+
MotionTracker.prototype.whileForwardingFinishEvent = function($elements, fn) {
|
3543
|
+
var doForward;
|
3544
|
+
if ($elements.length < 2) {
|
3545
|
+
return fn();
|
3546
|
+
}
|
3547
|
+
doForward = (function(_this) {
|
3548
|
+
return function(event) {
|
3549
|
+
if (!event.forwarded) {
|
3550
|
+
return u.each($elements, function(element) {
|
3551
|
+
var $element;
|
3552
|
+
$element = $(element);
|
3553
|
+
if (element !== event.target && _this.isActive($element)) {
|
3554
|
+
return _this.emitFinishEvent($element, {
|
3555
|
+
forwarded: true
|
3556
|
+
});
|
3557
|
+
}
|
3558
|
+
});
|
3559
|
+
}
|
3560
|
+
};
|
3561
|
+
})(this);
|
3562
|
+
$elements.on(this.finishEvent, doForward);
|
3563
|
+
return fn().then((function(_this) {
|
3564
|
+
return function() {
|
3565
|
+
return $elements.off(_this.finishEvent, doForward);
|
3566
|
+
};
|
3567
|
+
})(this));
|
3568
|
+
};
|
3569
|
+
|
3570
|
+
MotionTracker.prototype.reset = function() {
|
3571
|
+
return this.finish().then((function(_this) {
|
3572
|
+
return function() {
|
3573
|
+
_this.finishCount = 0;
|
3574
|
+
return _this.clusterCount = 0;
|
3575
|
+
};
|
3576
|
+
})(this));
|
3577
|
+
};
|
3578
|
+
|
3154
3579
|
return MotionTracker;
|
3155
3580
|
|
3156
3581
|
})();
|
@@ -3660,6 +4085,59 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
3660
4085
|
|
3661
4086
|
})(up.Record);
|
3662
4087
|
|
4088
|
+
}).call(this);
|
4089
|
+
(function() {
|
4090
|
+
var u,
|
4091
|
+
bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
|
4092
|
+
|
4093
|
+
u = up.util;
|
4094
|
+
|
4095
|
+
up.UrlSet = (function() {
|
4096
|
+
function UrlSet(urls, options) {
|
4097
|
+
this.urls = urls;
|
4098
|
+
if (options == null) {
|
4099
|
+
options = {};
|
4100
|
+
}
|
4101
|
+
this.isEqual = bind(this.isEqual, this);
|
4102
|
+
this.matchesAny = bind(this.matchesAny, this);
|
4103
|
+
this.doesMatchPrefix = bind(this.doesMatchPrefix, this);
|
4104
|
+
this.doesMatchFully = bind(this.doesMatchFully, this);
|
4105
|
+
this.matches = bind(this.matches, this);
|
4106
|
+
this.normalizeUrl = options.normalizeUrl || u.normalizeUrl;
|
4107
|
+
this.urls = u.map(this.urls, this.normalizeUrl);
|
4108
|
+
this.urls = u.compact(this.urls);
|
4109
|
+
}
|
4110
|
+
|
4111
|
+
UrlSet.prototype.matches = function(testUrl) {
|
4112
|
+
if (testUrl.substr(-1) === '*') {
|
4113
|
+
return this.doesMatchPrefix(testUrl.slice(0, -1));
|
4114
|
+
} else {
|
4115
|
+
return this.doesMatchFully(testUrl);
|
4116
|
+
}
|
4117
|
+
};
|
4118
|
+
|
4119
|
+
UrlSet.prototype.doesMatchFully = function(testUrl) {
|
4120
|
+
return u.contains(this.urls, testUrl);
|
4121
|
+
};
|
4122
|
+
|
4123
|
+
UrlSet.prototype.doesMatchPrefix = function(prefix) {
|
4124
|
+
return u.detect(this.urls, function(url) {
|
4125
|
+
return url.indexOf(prefix) === 0;
|
4126
|
+
});
|
4127
|
+
};
|
4128
|
+
|
4129
|
+
UrlSet.prototype.matchesAny = function(testUrls) {
|
4130
|
+
return u.detect(testUrls, this.matches);
|
4131
|
+
};
|
4132
|
+
|
4133
|
+
UrlSet.prototype.isEqual = function(otherSet) {
|
4134
|
+
return u.isEqual(this.urls, otherSet != null ? otherSet.urls : void 0);
|
4135
|
+
};
|
4136
|
+
|
4137
|
+
return UrlSet;
|
4138
|
+
|
4139
|
+
})();
|
4140
|
+
|
3663
4141
|
}).call(this);
|
3664
4142
|
|
3665
4143
|
/***
|
@@ -3845,9 +4323,9 @@ Internet Explorer 10 or lower
|
|
3845
4323
|
@return {boolean}
|
3846
4324
|
@internal
|
3847
4325
|
*/
|
3848
|
-
canCssTransition = function() {
|
4326
|
+
canCssTransition = u.memoize(function() {
|
3849
4327
|
return 'transition' in document.documentElement.style;
|
3850
|
-
};
|
4328
|
+
});
|
3851
4329
|
|
3852
4330
|
/***
|
3853
4331
|
Returns whether this browser supports the DOM event [`input`](https://developer.mozilla.org/de/docs/Web/Events/input).
|
@@ -3856,9 +4334,9 @@ Internet Explorer 10 or lower
|
|
3856
4334
|
@return {boolean}
|
3857
4335
|
@internal
|
3858
4336
|
*/
|
3859
|
-
canInputEvent = function() {
|
4337
|
+
canInputEvent = u.memoize(function() {
|
3860
4338
|
return 'oninput' in document.createElement('input');
|
3861
|
-
};
|
4339
|
+
});
|
3862
4340
|
|
3863
4341
|
/***
|
3864
4342
|
Returns whether this browser supports promises.
|
@@ -3867,9 +4345,9 @@ Internet Explorer 10 or lower
|
|
3867
4345
|
@return {boolean}
|
3868
4346
|
@internal
|
3869
4347
|
*/
|
3870
|
-
canPromise = function() {
|
4348
|
+
canPromise = u.memoize(function() {
|
3871
4349
|
return !!window.Promise;
|
3872
|
-
};
|
4350
|
+
});
|
3873
4351
|
|
3874
4352
|
/***
|
3875
4353
|
Returns whether this browser supports the [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData)
|
@@ -3879,9 +4357,9 @@ Internet Explorer 10 or lower
|
|
3879
4357
|
@return {boolean}
|
3880
4358
|
@experimental
|
3881
4359
|
*/
|
3882
|
-
canFormData = function() {
|
4360
|
+
canFormData = u.memoize(function() {
|
3883
4361
|
return !!window.FormData;
|
3884
|
-
};
|
4362
|
+
});
|
3885
4363
|
|
3886
4364
|
/***
|
3887
4365
|
Returns whether this browser supports the [`DOMParser`](https://developer.mozilla.org/en-US/docs/Web/API/DOMParser)
|
@@ -3891,9 +4369,9 @@ Internet Explorer 10 or lower
|
|
3891
4369
|
@return {boolean}
|
3892
4370
|
@internal
|
3893
4371
|
*/
|
3894
|
-
canDOMParser = function() {
|
4372
|
+
canDOMParser = u.memoize(function() {
|
3895
4373
|
return !!window.DOMParser;
|
3896
|
-
};
|
4374
|
+
});
|
3897
4375
|
|
3898
4376
|
/***
|
3899
4377
|
Returns whether this browser supports the [`debugging console`](https://developer.mozilla.org/en-US/docs/Web/API/Console).
|
@@ -3902,17 +4380,17 @@ Internet Explorer 10 or lower
|
|
3902
4380
|
@return {boolean}
|
3903
4381
|
@internal
|
3904
4382
|
*/
|
3905
|
-
canConsole = function() {
|
4383
|
+
canConsole = u.memoize(function() {
|
3906
4384
|
return window.console && console.debug && console.info && console.warn && console.error && console.group && console.groupCollapsed && console.groupEnd;
|
3907
|
-
};
|
3908
|
-
isRecentJQuery = function() {
|
4385
|
+
});
|
4386
|
+
isRecentJQuery = u.memoize(function() {
|
3909
4387
|
var major, minor, parts, version;
|
3910
4388
|
version = $.fn.jquery;
|
3911
4389
|
parts = version.split('.');
|
3912
4390
|
major = parseInt(parts[0]);
|
3913
4391
|
minor = parseInt(parts[1]);
|
3914
4392
|
return major >= 2 || (major === 1 && minor >= 9);
|
3915
|
-
};
|
4393
|
+
});
|
3916
4394
|
|
3917
4395
|
/***
|
3918
4396
|
Returns and deletes a cookie with the given name
|
@@ -4320,11 +4798,7 @@ This improves jQuery's [`on`](http://api.jquery.com/on/) in multiple ways:
|
|
4320
4798
|
eventProps = {};
|
4321
4799
|
}
|
4322
4800
|
event = $.Event(eventName, eventProps);
|
4323
|
-
|
4324
|
-
delete eventProps.$element;
|
4325
|
-
} else {
|
4326
|
-
$target = $(document);
|
4327
|
-
}
|
4801
|
+
$target = eventProps.$target || eventProps.$element || $(document);
|
4328
4802
|
logEmission(eventName, eventProps);
|
4329
4803
|
$target.trigger(event);
|
4330
4804
|
return event;
|
@@ -5184,7 +5658,7 @@ or when a matching fragment is [inserted via AJAX](/up.link) later.
|
|
5184
5658
|
var slice = [].slice;
|
5185
5659
|
|
5186
5660
|
up.syntax = (function($) {
|
5187
|
-
var DESTRUCTIBLE_CLASS, DESTRUCTORS_KEY, SYSTEM_MACRO_PRIORITIES, addDestructor, applyCompiler, buildCompiler, clean, compile, compiler, compilers, data, detectSystemMacroPriority, insertCompiler, isBooting, macro, macros, normalizeDestructor,
|
5661
|
+
var DESTRUCTIBLE_CLASS, DESTRUCTORS_KEY, SYSTEM_MACRO_PRIORITIES, addDestructor, applyCompiler, buildCompiler, clean, compile, compiler, compilers, data, detectSystemMacroPriority, insertCompiler, isBooting, macro, macros, normalizeDestructor, removeDestructors, reset, u;
|
5188
5662
|
u = up.util;
|
5189
5663
|
DESTRUCTIBLE_CLASS = 'up-destructible';
|
5190
5664
|
DESTRUCTORS_KEY = 'up-destructors';
|
@@ -5579,23 +6053,14 @@ or when a matching fragment is [inserted via AJAX](/up.link) later.
|
|
5579
6053
|
@internal
|
5580
6054
|
*/
|
5581
6055
|
clean = function($fragment) {
|
5582
|
-
|
5583
|
-
|
5584
|
-
|
5585
|
-
|
5586
|
-
|
5587
|
-
|
5588
|
-
|
5589
|
-
@internal
|
5590
|
-
*/
|
5591
|
-
prepareClean = function($fragment) {
|
5592
|
-
var $candidates, destructors;
|
5593
|
-
$candidates = u.selectInSubtree($fragment, "." + DESTRUCTIBLE_CLASS);
|
5594
|
-
destructors = u.map($candidates, function(candidate) {
|
5595
|
-
return $(candidate).data(DESTRUCTORS_KEY);
|
6056
|
+
var $destructibles;
|
6057
|
+
$destructibles = u.selectInSubtree($fragment, "." + DESTRUCTIBLE_CLASS);
|
6058
|
+
return u.each($destructibles, function(destructible) {
|
6059
|
+
var destructor;
|
6060
|
+
if (destructor = $(destructible).data(DESTRUCTORS_KEY)) {
|
6061
|
+
return destructor();
|
6062
|
+
}
|
5596
6063
|
});
|
5597
|
-
destructors = u.compact(destructors);
|
5598
|
-
return u.sequence.apply(u, destructors);
|
5599
6064
|
};
|
5600
6065
|
|
5601
6066
|
/***
|
@@ -5700,7 +6165,6 @@ or when a matching fragment is [inserted via AJAX](/up.link) later.
|
|
5700
6165
|
macro: macro,
|
5701
6166
|
compile: compile,
|
5702
6167
|
clean: clean,
|
5703
|
-
prepareClean: prepareClean,
|
5704
6168
|
data: data
|
5705
6169
|
};
|
5706
6170
|
})(jQuery);
|
@@ -5816,7 +6280,11 @@ In an Unpoly app, every page has an URL.
|
|
5816
6280
|
@internal
|
5817
6281
|
*/
|
5818
6282
|
replace = function(url) {
|
5819
|
-
|
6283
|
+
if (manipulate('replaceState', url)) {
|
6284
|
+
return up.emit('up:history:replaced', {
|
6285
|
+
url: url
|
6286
|
+
});
|
6287
|
+
}
|
5820
6288
|
};
|
5821
6289
|
|
5822
6290
|
/***
|
@@ -6046,7 +6514,7 @@ Unpoly will automatically be aware of sticky Bootstrap components such as
|
|
6046
6514
|
var slice = [].slice;
|
6047
6515
|
|
6048
6516
|
up.layout = (function($) {
|
6049
|
-
var anchoredRight, config, finishScrolling, firstHashTarget, fixedChildren, lastScrollTops, measureObstruction, reset, restoreScroll, reveal, revealHash, revealOrRestoreScroll, revealSelector, saveScroll, scroll, scrollAbruptlyNow, scrollTopKey, scrollTops, scrollWithAnimateNow, scrollableElementForViewport, scrollingTracker, u, viewportOf, viewportSelector, viewports, viewportsWithin;
|
6517
|
+
var absolutize, anchoredRight, config, finishScrolling, firstHashTarget, fixedChildren, lastScrollTops, measureObstruction, reset, restoreScroll, reveal, revealHash, revealOrRestoreScroll, revealSelector, saveScroll, scroll, scrollAbruptlyNow, scrollTopKey, scrollTops, scrollWithAnimateNow, scrollableElementForViewport, scrollingTracker, u, viewportOf, viewportSelector, viewports, viewportsWithin;
|
6050
6518
|
u = up.util;
|
6051
6519
|
|
6052
6520
|
/***
|
@@ -6084,7 +6552,7 @@ Unpoly will automatically be aware of sticky Bootstrap components such as
|
|
6084
6552
|
*/
|
6085
6553
|
config = u.config({
|
6086
6554
|
duration: 0,
|
6087
|
-
viewports: [
|
6555
|
+
viewports: ['.up-modal-viewport', '[up-viewport]'],
|
6088
6556
|
fixedTop: ['[up-fixed~=top]'],
|
6089
6557
|
fixedBottom: ['[up-fixed~=bottom]'],
|
6090
6558
|
anchoredRight: ['[up-anchored~=right]', '[up-fixed~=top]', '[up-fixed~=bottom]', '[up-fixed~=right]'],
|
@@ -6100,7 +6568,7 @@ Unpoly will automatically be aware of sticky Bootstrap components such as
|
|
6100
6568
|
reset = function() {
|
6101
6569
|
config.reset();
|
6102
6570
|
lastScrollTops.clear();
|
6103
|
-
return scrollingTracker.
|
6571
|
+
return scrollingTracker.reset();
|
6104
6572
|
};
|
6105
6573
|
|
6106
6574
|
/***
|
@@ -6197,6 +6665,9 @@ Unpoly will automatically be aware of sticky Bootstrap components such as
|
|
6197
6665
|
*/
|
6198
6666
|
finishScrolling = function(element) {
|
6199
6667
|
var $scrollable;
|
6668
|
+
if (!up.motion.isEnabled()) {
|
6669
|
+
return Promise.resolve();
|
6670
|
+
}
|
6200
6671
|
$scrollable = scrollableElementForViewport(element);
|
6201
6672
|
return scrollingTracker.finish($scrollable);
|
6202
6673
|
};
|
@@ -6206,7 +6677,9 @@ Unpoly will automatically be aware of sticky Bootstrap components such as
|
|
6206
6677
|
@internal
|
6207
6678
|
*/
|
6208
6679
|
anchoredRight = function() {
|
6209
|
-
|
6680
|
+
var selector;
|
6681
|
+
selector = config.anchoredRight.join(',');
|
6682
|
+
return $(selector);
|
6210
6683
|
};
|
6211
6684
|
|
6212
6685
|
/***
|
@@ -6219,11 +6692,11 @@ Unpoly will automatically be aware of sticky Bootstrap components such as
|
|
6219
6692
|
measurePosition = function(obstructor, cssAttr) {
|
6220
6693
|
var $obstructor, anchorPosition;
|
6221
6694
|
$obstructor = $(obstructor);
|
6222
|
-
anchorPosition = $obstructor
|
6695
|
+
anchorPosition = u.readComputedStyleNumber($obstructor, cssAttr);
|
6223
6696
|
if (!u.isPresent(anchorPosition)) {
|
6224
6697
|
up.fail("Fixed element %o must have a CSS attribute %s", $obstructor.get(0), cssAttr);
|
6225
6698
|
}
|
6226
|
-
return
|
6699
|
+
return anchorPosition + $obstructor.height();
|
6227
6700
|
};
|
6228
6701
|
fixedTopBottoms = (function() {
|
6229
6702
|
var i, len, ref, results;
|
@@ -6371,16 +6844,17 @@ Unpoly will automatically be aware of sticky Bootstrap components such as
|
|
6371
6844
|
}
|
6372
6845
|
};
|
6373
6846
|
viewportSelector = function() {
|
6374
|
-
return
|
6847
|
+
return config.viewports.join(',');
|
6375
6848
|
};
|
6376
6849
|
|
6377
6850
|
/***
|
6378
6851
|
Returns the viewport for the given element.
|
6379
6852
|
|
6380
|
-
|
6853
|
+
Returns `$(document)` if no better viewpoint could be found.
|
6381
6854
|
|
6382
6855
|
@function up.layout.viewportOf
|
6383
6856
|
@param {string|Element|jQuery} selectorOrElement
|
6857
|
+
@return {jQuery}
|
6384
6858
|
@internal
|
6385
6859
|
*/
|
6386
6860
|
viewportOf = function(selectorOrElement, options) {
|
@@ -6389,9 +6863,9 @@ Unpoly will automatically be aware of sticky Bootstrap components such as
|
|
6389
6863
|
options = {};
|
6390
6864
|
}
|
6391
6865
|
$element = $(selectorOrElement);
|
6392
|
-
$viewport = viewportSelector()
|
6393
|
-
if ($viewport.length === 0
|
6394
|
-
|
6866
|
+
$viewport = $element.closest(viewportSelector());
|
6867
|
+
if ($viewport.length === 0) {
|
6868
|
+
$viewport = $(document);
|
6395
6869
|
}
|
6396
6870
|
return $viewport;
|
6397
6871
|
};
|
@@ -6408,7 +6882,7 @@ Unpoly will automatically be aware of sticky Bootstrap components such as
|
|
6408
6882
|
viewportsWithin = function(selectorOrElement) {
|
6409
6883
|
var $element;
|
6410
6884
|
$element = $(selectorOrElement);
|
6411
|
-
return
|
6885
|
+
return u.selectInSubtree($element, viewportSelector());
|
6412
6886
|
};
|
6413
6887
|
|
6414
6888
|
/***
|
@@ -6418,7 +6892,7 @@ Unpoly will automatically be aware of sticky Bootstrap components such as
|
|
6418
6892
|
@internal
|
6419
6893
|
*/
|
6420
6894
|
viewports = function() {
|
6421
|
-
return
|
6895
|
+
return $(document).add(viewportSelector());
|
6422
6896
|
};
|
6423
6897
|
scrollTopKey = function(viewport) {
|
6424
6898
|
var $viewport;
|
@@ -6595,6 +7069,59 @@ Unpoly will automatically be aware of sticky Bootstrap components such as
|
|
6595
7069
|
return selector;
|
6596
7070
|
};
|
6597
7071
|
|
7072
|
+
/***
|
7073
|
+
@internal
|
7074
|
+
*/
|
7075
|
+
absolutize = function($element, options) {
|
7076
|
+
var $bounds, $fixedElements, $viewport, boundsStyle, fixedElement, i, len, moveTop, originalDims, originalOffset, top;
|
7077
|
+
options = u.options(options, {
|
7078
|
+
afterMeasure: u.noop
|
7079
|
+
});
|
7080
|
+
$viewport = up.layout.viewportOf($element);
|
7081
|
+
originalDims = u.measure($element, {
|
7082
|
+
relative: true,
|
7083
|
+
inner: true
|
7084
|
+
});
|
7085
|
+
originalOffset = $element.offset();
|
7086
|
+
options.afterMeasure();
|
7087
|
+
u.writeInlineStyle($element, {
|
7088
|
+
position: u.readComputedStyle($element, 'position') === 'static' ? 'static' : 'relative',
|
7089
|
+
top: 'auto',
|
7090
|
+
right: 'auto',
|
7091
|
+
bottom: 'auto',
|
7092
|
+
left: 'auto',
|
7093
|
+
width: '100%',
|
7094
|
+
height: '100%'
|
7095
|
+
});
|
7096
|
+
$bounds = $('<div class="up-bounds"></div>');
|
7097
|
+
boundsStyle = u.merge(originalDims, {
|
7098
|
+
position: 'absolute'
|
7099
|
+
});
|
7100
|
+
u.writeInlineStyle($bounds, boundsStyle);
|
7101
|
+
$bounds.insertBefore($element);
|
7102
|
+
$element.appendTo($bounds);
|
7103
|
+
top = originalDims.top;
|
7104
|
+
moveTop = function(diff) {
|
7105
|
+
if (diff !== 0) {
|
7106
|
+
top += diff;
|
7107
|
+
return u.writeInlineStyle($bounds, {
|
7108
|
+
top: top
|
7109
|
+
});
|
7110
|
+
}
|
7111
|
+
};
|
7112
|
+
moveTop(originalOffset.top - $element.offset().top);
|
7113
|
+
$fixedElements = up.layout.fixedChildren($element);
|
7114
|
+
for (i = 0, len = $fixedElements.length; i < len; i++) {
|
7115
|
+
fixedElement = $fixedElements[i];
|
7116
|
+
u.fixedToAbsolute(fixedElement, $viewport);
|
7117
|
+
}
|
7118
|
+
return {
|
7119
|
+
$element: $element,
|
7120
|
+
$bounds: $bounds,
|
7121
|
+
moveTop: moveTop
|
7122
|
+
};
|
7123
|
+
};
|
7124
|
+
|
6598
7125
|
/***
|
6599
7126
|
Marks this element as a scrolling container ("viewport").
|
6600
7127
|
|
@@ -6748,7 +7275,8 @@ Unpoly will automatically be aware of sticky Bootstrap components such as
|
|
6748
7275
|
restoreScroll: restoreScroll,
|
6749
7276
|
revealOrRestoreScroll: revealOrRestoreScroll,
|
6750
7277
|
anchoredRight: anchoredRight,
|
6751
|
-
fixedChildren: fixedChildren
|
7278
|
+
fixedChildren: fixedChildren,
|
7279
|
+
absolutize: absolutize
|
6752
7280
|
};
|
6753
7281
|
})(jQuery);
|
6754
7282
|
|
@@ -6776,7 +7304,7 @@ is built from these functions. You can use them to extend Unpoly from your
|
|
6776
7304
|
|
6777
7305
|
(function() {
|
6778
7306
|
up.dom = (function($) {
|
6779
|
-
var
|
7307
|
+
var bestMatchingSteps, bestPreflightSelector, config, destroy, detectScriptFixes, emitFragmentDestroy, emitFragmentDestroyed, emitFragmentInserted, emitFragmentKept, extract, findKeepPlan, first, firstInLayer, firstInPriority, fixScripts, hello, isRealElement, layerOf, markElementAsDestroying, matchesLayer, parseResponseDoc, processResponse, reload, replace, reset, resolveSelector, setSource, shouldExtractTitle, shouldLogDestruction, source, swapElements, transferKeepableElements, u, updateHistoryAndTitle;
|
6780
7308
|
u = up.util;
|
6781
7309
|
|
6782
7310
|
/***
|
@@ -6807,11 +7335,13 @@ is built from these functions. You can use them to extend Unpoly from your
|
|
6807
7335
|
};
|
6808
7336
|
setSource = function(element, sourceUrl) {
|
6809
7337
|
var $element;
|
6810
|
-
|
6811
|
-
|
6812
|
-
|
7338
|
+
if (sourceUrl !== false) {
|
7339
|
+
$element = $(element);
|
7340
|
+
if (u.isPresent(sourceUrl)) {
|
7341
|
+
sourceUrl = u.normalizeUrl(sourceUrl);
|
7342
|
+
}
|
7343
|
+
return $element.attr("up-source", sourceUrl);
|
6813
7344
|
}
|
6814
|
-
return $element.attr("up-source", sourceUrl);
|
6815
7345
|
};
|
6816
7346
|
|
6817
7347
|
/***
|
@@ -7189,7 +7719,7 @@ is built from these functions. You can use them to extend Unpoly from your
|
|
7189
7719
|
swapPromises = [];
|
7190
7720
|
for (i = 0, len = extractSteps.length; i < len; i++) {
|
7191
7721
|
step = extractSteps[i];
|
7192
|
-
up.log.group('
|
7722
|
+
up.log.group('Swapping fragment %s', step.selector, function() {
|
7193
7723
|
var swapOptions, swapPromise;
|
7194
7724
|
swapOptions = u.merge(options, u.only(step, 'origin', 'reveal'));
|
7195
7725
|
fixScripts(step.$new);
|
@@ -7275,14 +7805,14 @@ is built from these functions. You can use them to extend Unpoly from your
|
|
7275
7805
|
}
|
7276
7806
|
};
|
7277
7807
|
swapElements = function($old, $new, pseudoClass, transition, options) {
|
7278
|
-
var $
|
7808
|
+
var $parent, $wrapper, keepPlan, morphOptions, promise;
|
7279
7809
|
transition || (transition = 'none');
|
7280
7810
|
if (options.source === 'keep') {
|
7281
7811
|
options = u.merge(options, {
|
7282
7812
|
source: source($old)
|
7283
7813
|
});
|
7284
7814
|
}
|
7285
|
-
|
7815
|
+
setSource($new, options.source);
|
7286
7816
|
if (pseudoClass) {
|
7287
7817
|
$wrapper = $new.contents().wrapAll('<div class="up-insertion"></div>').parent();
|
7288
7818
|
if (pseudoClass === 'before') {
|
@@ -7298,41 +7828,34 @@ is built from these functions. You can use them to extend Unpoly from your
|
|
7298
7828
|
promise = promise.then(function() {
|
7299
7829
|
return u.unwrapElement($wrapper);
|
7300
7830
|
});
|
7831
|
+
return promise;
|
7301
7832
|
} else if (keepPlan = findKeepPlan($old, $new, options)) {
|
7302
7833
|
emitFragmentKept(keepPlan);
|
7303
|
-
|
7834
|
+
return Promise.resolve();
|
7304
7835
|
} else {
|
7305
7836
|
options.keepPlans = transferKeepableElements($old, $new, options);
|
7306
|
-
|
7307
|
-
|
7308
|
-
|
7309
|
-
|
7310
|
-
|
7311
|
-
|
7312
|
-
|
7313
|
-
|
7314
|
-
|
7315
|
-
|
7837
|
+
$parent = $old.parent();
|
7838
|
+
morphOptions = u.merge(options, {
|
7839
|
+
afterInsert: function() {
|
7840
|
+
up.hello($new, options);
|
7841
|
+
markElementAsDestroying($old);
|
7842
|
+
return emitFragmentDestroy($old, {
|
7843
|
+
log: false
|
7844
|
+
});
|
7845
|
+
},
|
7846
|
+
beforeDetach: function() {
|
7847
|
+
return up.syntax.clean($old);
|
7848
|
+
},
|
7849
|
+
afterDetach: function() {
|
7850
|
+
$old.remove();
|
7851
|
+
return emitFragmentDestroyed($old, {
|
7852
|
+
$parent: $parent,
|
7853
|
+
log: false
|
7854
|
+
});
|
7316
7855
|
}
|
7317
|
-
autofocus($new);
|
7318
|
-
hello($new, options);
|
7319
|
-
return up.morph($old, $new, transition, options);
|
7320
|
-
};
|
7321
|
-
promise = destroy($old, {
|
7322
|
-
clean: clean,
|
7323
|
-
beforeWipe: replacement,
|
7324
|
-
log: false
|
7325
7856
|
});
|
7857
|
+
return up.morph($old, $new, transition, morphOptions);
|
7326
7858
|
}
|
7327
|
-
return promise;
|
7328
|
-
};
|
7329
|
-
shouldSwapElementsDirectly = function($old, $new, transition, options) {
|
7330
|
-
var $both;
|
7331
|
-
$both = $old.add($new);
|
7332
|
-
return $old.is('body') || !up.motion.willAnimate($both, transition, options);
|
7333
|
-
};
|
7334
|
-
swapElementsDirectly = function($old, $new) {
|
7335
|
-
return $old.replaceWith($new);
|
7336
7859
|
};
|
7337
7860
|
transferKeepableElements = function($old, $new, options) {
|
7338
7861
|
var $keepable, $keepableClone, i, keepPlans, keepable, len, plan, ref;
|
@@ -7346,7 +7869,7 @@ is built from these functions. You can use them to extend Unpoly from your
|
|
7346
7869
|
descendantsOnly: true
|
7347
7870
|
}))) {
|
7348
7871
|
$keepableClone = $keepable.clone();
|
7349
|
-
|
7872
|
+
u.detachWith($keepable, $keepableClone);
|
7350
7873
|
plan.$newElement.replaceWith($keepable);
|
7351
7874
|
keepPlans.push(plan);
|
7352
7875
|
}
|
@@ -7533,12 +8056,10 @@ is built from these functions. You can use them to extend Unpoly from your
|
|
7533
8056
|
The fragment that has been inserted or updated.
|
7534
8057
|
@stable
|
7535
8058
|
*/
|
7536
|
-
emitFragmentInserted = function(
|
7537
|
-
var $fragment;
|
7538
|
-
$fragment = $(fragment);
|
8059
|
+
emitFragmentInserted = function($element, options) {
|
7539
8060
|
return up.emit('up:fragment:inserted', {
|
7540
|
-
$element: $
|
7541
|
-
message: ['Inserted fragment %o', $
|
8061
|
+
$element: $element,
|
8062
|
+
message: ['Inserted fragment %o', $element.get(0)],
|
7542
8063
|
origin: options.origin
|
7543
8064
|
});
|
7544
8065
|
};
|
@@ -7549,17 +8070,32 @@ is built from these functions. You can use them to extend Unpoly from your
|
|
7549
8070
|
});
|
7550
8071
|
return up.emit('up:fragment:kept', eventAttrs);
|
7551
8072
|
};
|
7552
|
-
|
7553
|
-
var
|
7554
|
-
|
7555
|
-
|
7556
|
-
if ($control.length && $control.get(0) !== document.activeElement) {
|
7557
|
-
return $control.focus();
|
8073
|
+
emitFragmentDestroy = function($element, options) {
|
8074
|
+
var message;
|
8075
|
+
if (shouldLogDestruction($element, options)) {
|
8076
|
+
message = ['Destroying fragment %o', $element.get(0)];
|
7558
8077
|
}
|
8078
|
+
return up.emit('up:fragment:destroy', {
|
8079
|
+
$element: $element,
|
8080
|
+
message: message
|
8081
|
+
});
|
8082
|
+
};
|
8083
|
+
emitFragmentDestroyed = function($element, options) {
|
8084
|
+
var $parent, message;
|
8085
|
+
if (shouldLogDestruction($element, options)) {
|
8086
|
+
message = ['Destroyed fragment %o', $element.get(0)];
|
8087
|
+
}
|
8088
|
+
$parent = options.$parent || up.fail("Missing { $parent } option");
|
8089
|
+
return up.emit('up:fragment:destroyed', {
|
8090
|
+
$target: $parent,
|
8091
|
+
$parent: $parent,
|
8092
|
+
$element: $element,
|
8093
|
+
message: message
|
8094
|
+
});
|
7559
8095
|
};
|
7560
8096
|
isRealElement = function($element) {
|
7561
8097
|
var unreal;
|
7562
|
-
unreal = '.up-
|
8098
|
+
unreal = '.up-destroying';
|
7563
8099
|
return $element.closest(unreal).length === 0;
|
7564
8100
|
};
|
7565
8101
|
|
@@ -7676,48 +8212,39 @@ is built from these functions. You can use them to extend Unpoly from your
|
|
7676
8212
|
@stable
|
7677
8213
|
*/
|
7678
8214
|
destroy = function(selectorOrElement, options) {
|
7679
|
-
var $element, animate,
|
8215
|
+
var $element, animate, wipe;
|
7680
8216
|
$element = $(selectorOrElement);
|
7681
8217
|
options = u.options(options, {
|
7682
8218
|
animation: false
|
7683
8219
|
});
|
7684
|
-
if (shouldLogDestruction($element, options)) {
|
7685
|
-
destroyMessage = ['Destroying fragment %o', $element.get(0)];
|
7686
|
-
destroyedMessage = ['Destroyed fragment %o', $element.get(0)];
|
7687
|
-
}
|
7688
8220
|
if ($element.length === 0) {
|
7689
8221
|
return Promise.resolve();
|
7690
|
-
} else {
|
7691
|
-
up.emit('up:fragment:destroy', {
|
7692
|
-
$element: $element,
|
7693
|
-
message: destroyMessage
|
7694
|
-
});
|
7695
|
-
$element.addClass('up-destroying');
|
7696
|
-
updateHistoryAndTitle(options);
|
7697
|
-
animate = function() {
|
7698
|
-
var animateOptions;
|
7699
|
-
animateOptions = up.motion.animateOptions(options);
|
7700
|
-
return up.motion.animate($element, options.animation, animateOptions);
|
7701
|
-
};
|
7702
|
-
beforeWipe = options.beforeWipe || Promise.resolve();
|
7703
|
-
wipe = function() {
|
7704
|
-
options.clean || (options.clean = function() {
|
7705
|
-
return up.syntax.clean($element);
|
7706
|
-
});
|
7707
|
-
options.clean();
|
7708
|
-
up.syntax.clean($element);
|
7709
|
-
up.emit('up:fragment:destroyed', {
|
7710
|
-
$element: $element,
|
7711
|
-
message: destroyedMessage
|
7712
|
-
});
|
7713
|
-
return $element.remove();
|
7714
|
-
};
|
7715
|
-
return animate().then(beforeWipe).then(wipe);
|
7716
8222
|
}
|
8223
|
+
markElementAsDestroying($element);
|
8224
|
+
emitFragmentDestroy($element, options);
|
8225
|
+
updateHistoryAndTitle(options);
|
8226
|
+
animate = function() {
|
8227
|
+
var animateOptions;
|
8228
|
+
animateOptions = up.motion.animateOptions(options);
|
8229
|
+
return up.motion.animate($element, options.animation, animateOptions);
|
8230
|
+
};
|
8231
|
+
wipe = function() {
|
8232
|
+
var $parent;
|
8233
|
+
$parent = $element.parent();
|
8234
|
+
up.syntax.clean($element);
|
8235
|
+
$element.remove();
|
8236
|
+
return emitFragmentDestroyed($element, {
|
8237
|
+
$parent: $parent
|
8238
|
+
});
|
8239
|
+
};
|
8240
|
+
return animate().then(wipe);
|
7717
8241
|
};
|
7718
8242
|
shouldLogDestruction = function($element, options) {
|
7719
8243
|
return options.log !== false && !$element.is('.up-placeholder, .up-tooltip, .up-modal, .up-popup');
|
7720
8244
|
};
|
8245
|
+
markElementAsDestroying = function($element) {
|
8246
|
+
return $element.addClass('up-destroying');
|
8247
|
+
};
|
7721
8248
|
|
7722
8249
|
/***
|
7723
8250
|
Before a page fragment is being [destroyed](/up.destroy), this
|
@@ -7733,15 +8260,17 @@ is built from these functions. You can use them to extend Unpoly from your
|
|
7733
8260
|
*/
|
7734
8261
|
|
7735
8262
|
/***
|
7736
|
-
This event is [emitted](/up.emit)
|
7737
|
-
page fragment is removed from the DOM.
|
8263
|
+
This event is [emitted](/up.emit) after a page fragment was [destroyed](/up.destroy) and removed from the DOM.
|
7738
8264
|
|
7739
|
-
If the destruction is animated, this event is emitted after
|
7740
|
-
|
8265
|
+
If the destruction is animated, this event is emitted after the animation has ended.
|
8266
|
+
|
8267
|
+
The event is emitted on the parent element of the fragment that was removed.
|
7741
8268
|
|
7742
8269
|
@event up:fragment:destroyed
|
7743
8270
|
@param {jQuery} event.$element
|
7744
|
-
The page fragment that
|
8271
|
+
The page fragment that has been removed from the DOM.
|
8272
|
+
@param {jQuery} event.$parent
|
8273
|
+
The parent element of the fragment that has been removed from the DOM.
|
7745
8274
|
@stable
|
7746
8275
|
*/
|
7747
8276
|
|
@@ -7848,7 +8377,7 @@ You can define custom animations using [`up.transition()`](/up.transition) and
|
|
7848
8377
|
var slice = [].slice;
|
7849
8378
|
|
7850
8379
|
up.motion = (function($) {
|
7851
|
-
var animate, animateOptions,
|
8380
|
+
var animCount, animate, animateNow, animateOptions, composeTransitionFn, config, defaultNamedAnimations, defaultNamedTransitions, findAnimationFn, findNamedAnimation, findTransitionFn, finish, isEnabled, isNone, isSingletonElement, morph, motionTracker, namedAnimations, namedTransitions, registerAnimation, registerTransition, reset, skipAnimate, snapshot, swapElementsDirectly, translateCss, u, willAnimate;
|
7852
8381
|
u = up.util;
|
7853
8382
|
namedAnimations = {};
|
7854
8383
|
defaultNamedAnimations = {};
|
@@ -7886,7 +8415,7 @@ You can define custom animations using [`up.transition()`](/up.transition) and
|
|
7886
8415
|
enabled: true
|
7887
8416
|
});
|
7888
8417
|
reset = function() {
|
7889
|
-
|
8418
|
+
motionTracker.reset();
|
7890
8419
|
namedAnimations = u.copy(defaultNamedAnimations);
|
7891
8420
|
namedTransitions = u.copy(defaultNamedTransitions);
|
7892
8421
|
return config.reset();
|
@@ -7978,44 +8507,43 @@ You can define custom animations using [`up.transition()`](/up.transition) and
|
|
7978
8507
|
@stable
|
7979
8508
|
*/
|
7980
8509
|
animate = function(elementOrSelector, animation, options) {
|
7981
|
-
var $element;
|
8510
|
+
var $element, animationFn, runNow, willRun;
|
7982
8511
|
$element = $(elementOrSelector);
|
7983
8512
|
options = animateOptions(options);
|
7984
|
-
|
7985
|
-
|
7986
|
-
|
7987
|
-
|
7988
|
-
return
|
7989
|
-
}
|
7990
|
-
|
7991
|
-
|
7992
|
-
|
7993
|
-
|
7994
|
-
return up.fail('Animation must be a function, animation name or object of CSS properties, but it was %o', animation);
|
7995
|
-
}
|
7996
|
-
});
|
8513
|
+
animationFn = findAnimationFn(animation);
|
8514
|
+
willRun = willAnimate($element, animation, options);
|
8515
|
+
if (willRun) {
|
8516
|
+
runNow = function() {
|
8517
|
+
return animationFn($element, options);
|
8518
|
+
};
|
8519
|
+
return motionTracker.claim($element, runNow, options);
|
8520
|
+
} else {
|
8521
|
+
return skipAnimate($element, animation);
|
8522
|
+
}
|
7997
8523
|
};
|
7998
8524
|
willAnimate = function($elements, animationOrTransition, options) {
|
7999
8525
|
options = animateOptions(options);
|
8000
|
-
return isEnabled() && !isNone(animationOrTransition) && options.duration > 0 &&
|
8526
|
+
return isEnabled() && !isNone(animationOrTransition) && options.duration > 0 && !isSingletonElement($elements);
|
8527
|
+
};
|
8528
|
+
isSingletonElement = function($element) {
|
8529
|
+
return $element.is('body');
|
8001
8530
|
};
|
8002
8531
|
skipAnimate = function($element, animation) {
|
8003
8532
|
if (u.isOptions(animation)) {
|
8004
|
-
$element
|
8533
|
+
u.writeInlineStyle($element, animation);
|
8005
8534
|
}
|
8006
8535
|
return Promise.resolve();
|
8007
8536
|
};
|
8537
|
+
animCount = 0;
|
8008
8538
|
|
8009
8539
|
/***
|
8010
8540
|
Animates the given element's CSS properties using CSS transitions.
|
8011
8541
|
|
8012
|
-
|
8013
|
-
|
8014
|
-
|
8015
|
-
To improve performance, the element will be forced into compositing for
|
8016
|
-
the duration of the animation.
|
8542
|
+
Does not track the animation, nor does it finishes existing animations
|
8543
|
+
(use `up.motion.animate()` for that). It does, however, listen to the motionTracker's
|
8544
|
+
finish event.
|
8017
8545
|
|
8018
|
-
@function
|
8546
|
+
@function animateNow
|
8019
8547
|
@param {Element|jQuery|string} elementOrSelector
|
8020
8548
|
The element to animate.
|
8021
8549
|
@param {Object} lastFrame
|
@@ -8032,55 +8560,13 @@ You can define custom animations using [`up.transition()`](/up.transition) and
|
|
8032
8560
|
A promise that fulfills when the animation ends.
|
8033
8561
|
@internal
|
8034
8562
|
*/
|
8035
|
-
|
8036
|
-
var
|
8037
|
-
|
8038
|
-
|
8039
|
-
|
8040
|
-
|
8041
|
-
|
8042
|
-
'transition-duration': options.duration + "ms",
|
8043
|
-
'transition-delay': options.delay + "ms",
|
8044
|
-
'transition-timing-function': options.easing
|
8045
|
-
};
|
8046
|
-
oldTransition = $element.css(Object.keys(transition));
|
8047
|
-
deferred = u.newDeferred();
|
8048
|
-
fulfill = function() {
|
8049
|
-
return deferred.resolve();
|
8050
|
-
};
|
8051
|
-
onTransitionEnd = function(event) {
|
8052
|
-
var completedProperty;
|
8053
|
-
completedProperty = event.originalEvent.propertyName;
|
8054
|
-
if (u.contains(transitionProperties, completedProperty)) {
|
8055
|
-
return fulfill();
|
8056
|
-
}
|
8057
|
-
};
|
8058
|
-
onFinish = fulfill;
|
8059
|
-
$element.on(motionTracker.finishEvent, onFinish);
|
8060
|
-
$element.on('transitionend', onTransitionEnd);
|
8061
|
-
transitionTimingTolerance = 5;
|
8062
|
-
cancelFallbackTimer = u.setTimer(options.duration + transitionTimingTolerance, fulfill);
|
8063
|
-
deferred.then(function() {
|
8064
|
-
var hadTransitionBefore;
|
8065
|
-
$element.off(motionTracker.finishEvent, onFinish);
|
8066
|
-
$element.off('transitionend', onTransitionEnd);
|
8067
|
-
clearTimeout(cancelFallbackTimer);
|
8068
|
-
undoCompositing();
|
8069
|
-
$element.css({
|
8070
|
-
'transition': 'none'
|
8071
|
-
});
|
8072
|
-
hadTransitionBefore = !(oldTransition['transition-property'] === 'none' || (oldTransition['transition-property'] === 'all' && oldTransition['transition-duration'][0] === '0'));
|
8073
|
-
if (hadTransitionBefore) {
|
8074
|
-
u.forceRepaint($element);
|
8075
|
-
return $element.css(oldTransition);
|
8076
|
-
}
|
8077
|
-
});
|
8078
|
-
undoCompositing = u.forceCompositing($element);
|
8079
|
-
$element.css(transition);
|
8080
|
-
$element.css(lastFrame);
|
8081
|
-
return deferred.promise();
|
8082
|
-
};
|
8083
|
-
return motionTracker.start($element, startCssTransition);
|
8563
|
+
animateNow = function($element, lastFrame, options) {
|
8564
|
+
var cssTransition;
|
8565
|
+
options = u.merge(options, {
|
8566
|
+
finishEvent: motionTracker.finishEvent
|
8567
|
+
});
|
8568
|
+
cssTransition = new up.CssTransition($element, lastFrame, options);
|
8569
|
+
return cssTransition.start();
|
8084
8570
|
};
|
8085
8571
|
|
8086
8572
|
/***
|
@@ -8101,58 +8587,13 @@ You can define custom animations using [`up.transition()`](/up.transition) and
|
|
8101
8587
|
consolidatedOptions.easing = u.option(userOptions.easing, u.presentAttr($element, 'up-easing'), moduleDefaults.easing, config.easing);
|
8102
8588
|
consolidatedOptions.duration = Number(u.option(userOptions.duration, u.presentAttr($element, 'up-duration'), moduleDefaults.duration, config.duration));
|
8103
8589
|
consolidatedOptions.delay = Number(u.option(userOptions.delay, u.presentAttr($element, 'up-delay'), moduleDefaults.delay, config.delay));
|
8104
|
-
consolidatedOptions.
|
8590
|
+
consolidatedOptions.trackMotion = userOptions.trackMotion;
|
8105
8591
|
return consolidatedOptions;
|
8106
8592
|
};
|
8107
8593
|
findNamedAnimation = function(name) {
|
8108
8594
|
return namedAnimations[name] || up.fail("Unknown animation %o", name);
|
8109
8595
|
};
|
8110
8596
|
|
8111
|
-
/***
|
8112
|
-
@function withGhosts
|
8113
|
-
@return {Promise}
|
8114
|
-
@internal
|
8115
|
-
*/
|
8116
|
-
withGhosts = function($old, $new, options, transitionFn) {
|
8117
|
-
var $viewport, newCopy, newScrollTop, oldCopy, oldScrollTop, scrollOptions;
|
8118
|
-
if (options.copy === false || $old.is('.up-ghost') || $new.is('.up-ghost')) {
|
8119
|
-
return transitionFn($old, $new, options);
|
8120
|
-
}
|
8121
|
-
oldCopy = void 0;
|
8122
|
-
newCopy = void 0;
|
8123
|
-
oldScrollTop = void 0;
|
8124
|
-
newScrollTop = void 0;
|
8125
|
-
$viewport = up.layout.viewportOf($old);
|
8126
|
-
u.temporaryCss($new, {
|
8127
|
-
display: 'none'
|
8128
|
-
}, function() {
|
8129
|
-
oldCopy = prependCopy($old, $viewport);
|
8130
|
-
return oldScrollTop = $viewport.scrollTop();
|
8131
|
-
});
|
8132
|
-
$old.hide();
|
8133
|
-
scrollOptions = u.merge(options, {
|
8134
|
-
duration: 0
|
8135
|
-
});
|
8136
|
-
return up.layout.revealOrRestoreScroll($new, scrollOptions).then(function() {
|
8137
|
-
var $bothGhosts, $bothOriginals, restoreNewOpacity, transitionDone;
|
8138
|
-
newCopy = prependCopy($new, $viewport);
|
8139
|
-
newScrollTop = $viewport.scrollTop();
|
8140
|
-
oldCopy.moveTop(newScrollTop - oldScrollTop);
|
8141
|
-
restoreNewOpacity = u.temporaryCss($new, {
|
8142
|
-
opacity: '0'
|
8143
|
-
});
|
8144
|
-
transitionDone = transitionFn(oldCopy.$ghost, newCopy.$ghost, options);
|
8145
|
-
$bothGhosts = oldCopy.$ghost.add(newCopy.$ghost);
|
8146
|
-
$bothOriginals = $old.add($new);
|
8147
|
-
motionTracker.forwardFinishEvent($bothOriginals, $bothGhosts, transitionDone);
|
8148
|
-
return transitionDone.then(function() {
|
8149
|
-
restoreNewOpacity();
|
8150
|
-
oldCopy.$bounds.remove();
|
8151
|
-
return newCopy.$bounds.remove();
|
8152
|
-
});
|
8153
|
-
});
|
8154
|
-
};
|
8155
|
-
|
8156
8597
|
/***
|
8157
8598
|
Completes [animations](/up.animate) and [transitions](/up.morph).
|
8158
8599
|
|
@@ -8175,12 +8616,16 @@ You can define custom animations using [`up.transition()`](/up.transition) and
|
|
8175
8616
|
};
|
8176
8617
|
|
8177
8618
|
/***
|
8178
|
-
Performs an animated transition between
|
8619
|
+
Performs an animated transition between the `source` and `target` elements.
|
8620
|
+
|
8179
8621
|
Transitions are implement by performing two animations in parallel,
|
8180
|
-
causing
|
8622
|
+
causing `source` to disappear and the `target` to appear.
|
8181
8623
|
|
8182
|
-
|
8183
|
-
|
8624
|
+
- `target` is [inserted before](https://developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore) `source`
|
8625
|
+
- `source` is removed from the [document flow](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Positioning) with `position: absolute`.
|
8626
|
+
It will be positioned over its original place in the flow that is now occupied by `target`.
|
8627
|
+
- Both `source` and `target` are animated in parallel
|
8628
|
+
- `source` is removed from the DOM
|
8184
8629
|
|
8185
8630
|
\#\#\# Named transitions
|
8186
8631
|
|
@@ -8236,35 +8681,65 @@ You can define custom animations using [`up.transition()`](/up.transition) and
|
|
8236
8681
|
Whether to reveal the new element by scrolling its parent viewport.
|
8237
8682
|
@return {Promise}
|
8238
8683
|
A promise that fulfills when the transition ends.
|
8239
|
-
@
|
8684
|
+
@experimental
|
8240
8685
|
*/
|
8241
8686
|
morph = function(source, target, transitionObject, options) {
|
8242
|
-
var $both, $new, $old, transitionFn, willMorph;
|
8687
|
+
var $both, $new, $old, $viewport, oldRemote, promise, scrollNew, scrollTopBeforeReveal, trackable, transitionFn, willMorph;
|
8243
8688
|
options = u.options(options);
|
8244
8689
|
options = u.assign(options, animateOptions(options));
|
8245
8690
|
$old = $(source);
|
8246
8691
|
$new = $(target);
|
8247
8692
|
$both = $old.add($new);
|
8248
8693
|
transitionFn = findTransitionFn(transitionObject);
|
8249
|
-
willMorph = willAnimate($
|
8250
|
-
|
8251
|
-
|
8252
|
-
|
8253
|
-
|
8254
|
-
|
8255
|
-
|
8256
|
-
|
8257
|
-
|
8694
|
+
willMorph = willAnimate($old, transitionFn, options);
|
8695
|
+
options.afterInsert || (options.afterInsert = u.noop);
|
8696
|
+
options.beforeDetach || (options.beforeDetach = u.noop);
|
8697
|
+
options.afterDetach || (options.afterDetach = u.noop);
|
8698
|
+
scrollNew = function() {
|
8699
|
+
var scrollOptions;
|
8700
|
+
scrollOptions = u.merge(options, {
|
8701
|
+
duration: 0
|
8702
|
+
});
|
8703
|
+
return up.layout.revealOrRestoreScroll($new, scrollOptions);
|
8704
|
+
};
|
8705
|
+
if (willMorph) {
|
8706
|
+
if (motionTracker.isActive($old) && options.trackMotion === false) {
|
8707
|
+
return transitionFn($old, $new, options);
|
8708
|
+
}
|
8709
|
+
up.puts('Morphing %o to %o with transition %o', $old.get(0), $new.get(0), transitionObject);
|
8710
|
+
$viewport = up.layout.viewportOf($old);
|
8711
|
+
scrollTopBeforeReveal = $viewport.scrollTop();
|
8712
|
+
oldRemote = up.layout.absolutize($old, {
|
8713
|
+
afterMeasure: function() {
|
8714
|
+
$new.insertBefore($old);
|
8715
|
+
return options.afterInsert();
|
8258
8716
|
}
|
8259
8717
|
});
|
8260
|
-
|
8261
|
-
|
8262
|
-
|
8263
|
-
|
8264
|
-
|
8718
|
+
trackable = function() {
|
8719
|
+
var promise;
|
8720
|
+
promise = scrollNew();
|
8721
|
+
promise = promise.then(function() {
|
8722
|
+
var scrollTopAfterReveal;
|
8723
|
+
scrollTopAfterReveal = $viewport.scrollTop();
|
8724
|
+
oldRemote.moveTop(scrollTopAfterReveal - scrollTopBeforeReveal);
|
8725
|
+
return transitionFn($old, $new, options);
|
8726
|
+
});
|
8727
|
+
promise = promise.then(function() {
|
8728
|
+
options.beforeDetach();
|
8729
|
+
$old.detach();
|
8730
|
+
oldRemote.$bounds.remove();
|
8731
|
+
return options.afterDetach();
|
8732
|
+
});
|
8733
|
+
return promise;
|
8734
|
+
};
|
8735
|
+
return motionTracker.claim($both, trackable, options);
|
8265
8736
|
} else {
|
8266
|
-
options.
|
8267
|
-
|
8737
|
+
options.beforeDetach();
|
8738
|
+
swapElementsDirectly($old, $new);
|
8739
|
+
options.afterInsert();
|
8740
|
+
options.afterDetach();
|
8741
|
+
promise = scrollNew();
|
8742
|
+
return promise;
|
8268
8743
|
}
|
8269
8744
|
};
|
8270
8745
|
findTransitionFn = function(object) {
|
@@ -8274,87 +8749,46 @@ You can define custom animations using [`up.transition()`](/up.transition) and
|
|
8274
8749
|
} else if (u.isFunction(object)) {
|
8275
8750
|
return object;
|
8276
8751
|
} else if (u.isArray(object)) {
|
8277
|
-
|
8278
|
-
return void 0;
|
8279
|
-
} else {
|
8280
|
-
return function($old, $new, options) {
|
8281
|
-
return Promise.all([animate($old, object[0], options), animate($new, object[1], options)]);
|
8282
|
-
};
|
8283
|
-
}
|
8752
|
+
return composeTransitionFn.apply(null, object);
|
8284
8753
|
} else if (u.isString(object)) {
|
8285
8754
|
if (object.indexOf('/') >= 0) {
|
8286
|
-
return
|
8755
|
+
return composeTransitionFn.apply(null, object.split('/'));
|
8287
8756
|
} else if (namedTransition = namedTransitions[object]) {
|
8288
8757
|
return findTransitionFn(namedTransition);
|
8289
8758
|
}
|
8759
|
+
} else {
|
8760
|
+
return up.fail("Unknown transition %o", object);
|
8290
8761
|
}
|
8291
8762
|
};
|
8292
|
-
|
8293
|
-
|
8294
|
-
|
8295
|
-
|
8296
|
-
|
8297
|
-
|
8298
|
-
|
8299
|
-
|
8300
|
-
|
8301
|
-
|
8302
|
-
|
8303
|
-
$old.hide();
|
8304
|
-
scrollOptions = u.merge(options, {
|
8305
|
-
duration: 0
|
8306
|
-
});
|
8307
|
-
return up.layout.revealOrRestoreScroll($new, scrollOptions);
|
8763
|
+
composeTransitionFn = function(oldAnimation, newAnimation) {
|
8764
|
+
var newAnimationFn, oldAnimationFn;
|
8765
|
+
if (isNone(oldAnimation) && isNone(oldAnimation)) {
|
8766
|
+
return void 0;
|
8767
|
+
} else {
|
8768
|
+
oldAnimationFn = findAnimationFn(oldAnimation) || u.asyncNoop;
|
8769
|
+
newAnimationFn = findAnimationFn(newAnimation) || u.asyncNoop;
|
8770
|
+
return function($old, $new, options) {
|
8771
|
+
return Promise.all([oldAnimationFn($old, options), newAnimationFn($new, options)]);
|
8772
|
+
};
|
8773
|
+
}
|
8308
8774
|
};
|
8309
|
-
|
8310
|
-
|
8311
|
-
|
8312
|
-
|
8313
|
-
|
8314
|
-
|
8315
|
-
|
8316
|
-
|
8317
|
-
|
8318
|
-
|
8319
|
-
|
8320
|
-
|
8321
|
-
|
8322
|
-
position: $element.css('position') === 'static' ? 'static' : 'relative',
|
8323
|
-
top: 'auto',
|
8324
|
-
right: 'auto',
|
8325
|
-
bottom: 'auto',
|
8326
|
-
left: 'auto',
|
8327
|
-
width: '100%',
|
8328
|
-
height: '100%'
|
8329
|
-
});
|
8330
|
-
$ghost.addClass('up-ghost');
|
8331
|
-
$bounds = $('<div class="up-bounds"></div>');
|
8332
|
-
$bounds.css({
|
8333
|
-
position: 'absolute'
|
8334
|
-
});
|
8335
|
-
$bounds.css(elementDims);
|
8336
|
-
top = elementDims.top;
|
8337
|
-
moveTop = function(diff) {
|
8338
|
-
if (diff !== 0) {
|
8339
|
-
top += diff;
|
8340
|
-
return $bounds.css({
|
8341
|
-
top: top
|
8342
|
-
});
|
8343
|
-
}
|
8344
|
-
};
|
8345
|
-
$ghost.appendTo($bounds);
|
8346
|
-
$bounds.insertBefore($element);
|
8347
|
-
moveTop($element.offset().top - $ghost.offset().top);
|
8348
|
-
$fixedElements = up.layout.fixedChildren($ghost);
|
8349
|
-
for (i = 0, len = $fixedElements.length; i < len; i++) {
|
8350
|
-
fixedElement = $fixedElements[i];
|
8351
|
-
u.fixedToAbsolute(fixedElement, $viewport);
|
8775
|
+
findAnimationFn = function(object) {
|
8776
|
+
if (isNone(object)) {
|
8777
|
+
return void 0;
|
8778
|
+
} else if (u.isFunction(object)) {
|
8779
|
+
return object;
|
8780
|
+
} else if (u.isString(object)) {
|
8781
|
+
return findNamedAnimation(object);
|
8782
|
+
} else if (u.isOptions(object)) {
|
8783
|
+
return function($element, options) {
|
8784
|
+
return animateNow($element, object, options);
|
8785
|
+
};
|
8786
|
+
} else {
|
8787
|
+
return up.fail('Unknown animation %o', object);
|
8352
8788
|
}
|
8353
|
-
|
8354
|
-
|
8355
|
-
|
8356
|
-
moveTop: moveTop
|
8357
|
-
};
|
8789
|
+
};
|
8790
|
+
swapElementsDirectly = function($old, $new) {
|
8791
|
+
return $old.replaceWith($new);
|
8358
8792
|
};
|
8359
8793
|
|
8360
8794
|
/***
|
@@ -8391,7 +8825,7 @@ You can define custom animations using [`up.transition()`](/up.transition) and
|
|
8391
8825
|
@stable
|
8392
8826
|
*/
|
8393
8827
|
registerTransition = function(name, transition) {
|
8394
|
-
return namedTransitions[name] = transition;
|
8828
|
+
return namedTransitions[name] = findTransitionFn(transition);
|
8395
8829
|
};
|
8396
8830
|
|
8397
8831
|
/***
|
@@ -8401,7 +8835,7 @@ You can define custom animations using [`up.transition()`](/up.transition) and
|
|
8401
8835
|
|
8402
8836
|
up.animation('fade-in', function($element, options) {
|
8403
8837
|
$element.css(opacity: 0);
|
8404
|
-
up.animate($
|
8838
|
+
up.animate($element, { opacity: 1 }, options);
|
8405
8839
|
})
|
8406
8840
|
|
8407
8841
|
It is recommended that your definitions always end by calling
|
@@ -8427,7 +8861,7 @@ You can define custom animations using [`up.transition()`](/up.transition) and
|
|
8427
8861
|
@stable
|
8428
8862
|
*/
|
8429
8863
|
registerAnimation = function(name, animation) {
|
8430
|
-
return namedAnimations[name] = animation;
|
8864
|
+
return namedAnimations[name] = findAnimationFn(animation);
|
8431
8865
|
};
|
8432
8866
|
snapshot = function() {
|
8433
8867
|
defaultNamedAnimations = u.copy(namedAnimations);
|
@@ -8442,21 +8876,21 @@ You can define custom animations using [`up.transition()`](/up.transition) and
|
|
8442
8876
|
@internal
|
8443
8877
|
*/
|
8444
8878
|
isNone = function(animationOrTransition) {
|
8445
|
-
return !animationOrTransition || animationOrTransition === 'none' ||
|
8879
|
+
return !animationOrTransition || animationOrTransition === 'none' || u.isBlank(animationOrTransition);
|
8446
8880
|
};
|
8447
|
-
registerAnimation('fade-in', function($
|
8448
|
-
|
8881
|
+
registerAnimation('fade-in', function($element, options) {
|
8882
|
+
u.writeInlineStyle($element, {
|
8449
8883
|
opacity: 0
|
8450
8884
|
});
|
8451
|
-
return
|
8885
|
+
return animateNow($element, {
|
8452
8886
|
opacity: 1
|
8453
8887
|
}, options);
|
8454
8888
|
});
|
8455
|
-
registerAnimation('fade-out', function($
|
8456
|
-
|
8889
|
+
registerAnimation('fade-out', function($element, options) {
|
8890
|
+
u.writeInlineStyle($element, {
|
8457
8891
|
opacity: 1
|
8458
8892
|
});
|
8459
|
-
return
|
8893
|
+
return animateNow($element, {
|
8460
8894
|
opacity: 0
|
8461
8895
|
}, options);
|
8462
8896
|
});
|
@@ -8465,84 +8899,84 @@ You can define custom animations using [`up.transition()`](/up.transition) and
|
|
8465
8899
|
transform: "translate(" + x + "px, " + y + "px)"
|
8466
8900
|
};
|
8467
8901
|
};
|
8468
|
-
registerAnimation('move-to-top', function($
|
8902
|
+
registerAnimation('move-to-top', function($element, options) {
|
8469
8903
|
var box, travelDistance;
|
8470
|
-
|
8471
|
-
box = u.measure($
|
8904
|
+
u.writeInlineStyle($element, translateCss(0, 0));
|
8905
|
+
box = u.measure($element);
|
8472
8906
|
travelDistance = box.top + box.height;
|
8473
|
-
return
|
8907
|
+
return animateNow($element, translateCss(0, -travelDistance), options);
|
8474
8908
|
});
|
8475
|
-
registerAnimation('move-from-top', function($
|
8909
|
+
registerAnimation('move-from-top', function($element, options) {
|
8476
8910
|
var box, travelDistance;
|
8477
|
-
|
8478
|
-
box = u.measure($
|
8911
|
+
u.writeInlineStyle($element, translateCss(0, 0));
|
8912
|
+
box = u.measure($element);
|
8479
8913
|
travelDistance = box.top + box.height;
|
8480
|
-
|
8481
|
-
return
|
8914
|
+
u.writeInlineStyle($element, translateCss(0, -travelDistance));
|
8915
|
+
return animateNow($element, translateCss(0, 0), options);
|
8482
8916
|
});
|
8483
|
-
registerAnimation('move-to-bottom', function($
|
8917
|
+
registerAnimation('move-to-bottom', function($element, options) {
|
8484
8918
|
var box, travelDistance;
|
8485
|
-
|
8486
|
-
box = u.measure($
|
8919
|
+
u.writeInlineStyle($element, translateCss(0, 0));
|
8920
|
+
box = u.measure($element);
|
8487
8921
|
travelDistance = u.clientSize().height - box.top;
|
8488
|
-
return
|
8922
|
+
return animateNow($element, translateCss(0, travelDistance), options);
|
8489
8923
|
});
|
8490
|
-
registerAnimation('move-from-bottom', function($
|
8924
|
+
registerAnimation('move-from-bottom', function($element, options) {
|
8491
8925
|
var box, travelDistance;
|
8492
|
-
|
8493
|
-
box = u.measure($
|
8926
|
+
u.writeInlineStyle($element, translateCss(0, 0));
|
8927
|
+
box = u.measure($element);
|
8494
8928
|
travelDistance = u.clientSize().height - box.top;
|
8495
|
-
|
8496
|
-
return
|
8929
|
+
u.writeInlineStyle($element, translateCss(0, travelDistance));
|
8930
|
+
return animateNow($element, translateCss(0, 0), options);
|
8497
8931
|
});
|
8498
|
-
registerAnimation('move-to-left', function($
|
8932
|
+
registerAnimation('move-to-left', function($element, options) {
|
8499
8933
|
var box, travelDistance;
|
8500
|
-
|
8501
|
-
box = u.measure($
|
8934
|
+
u.writeInlineStyle($element, translateCss(0, 0));
|
8935
|
+
box = u.measure($element);
|
8502
8936
|
travelDistance = box.left + box.width;
|
8503
|
-
return
|
8937
|
+
return animateNow($element, translateCss(-travelDistance, 0), options);
|
8504
8938
|
});
|
8505
|
-
registerAnimation('move-from-left', function($
|
8939
|
+
registerAnimation('move-from-left', function($element, options) {
|
8506
8940
|
var box, travelDistance;
|
8507
|
-
|
8508
|
-
box = u.measure($
|
8941
|
+
u.writeInlineStyle($element, translateCss(0, 0));
|
8942
|
+
box = u.measure($element);
|
8509
8943
|
travelDistance = box.left + box.width;
|
8510
|
-
|
8511
|
-
return
|
8944
|
+
u.writeInlineStyle($element, translateCss(-travelDistance, 0));
|
8945
|
+
return animateNow($element, translateCss(0, 0), options);
|
8512
8946
|
});
|
8513
|
-
registerAnimation('move-to-right', function($
|
8947
|
+
registerAnimation('move-to-right', function($element, options) {
|
8514
8948
|
var box, travelDistance;
|
8515
|
-
|
8516
|
-
box = u.measure($
|
8949
|
+
u.writeInlineStyle($element, translateCss(0, 0));
|
8950
|
+
box = u.measure($element);
|
8517
8951
|
travelDistance = u.clientSize().width - box.left;
|
8518
|
-
return
|
8952
|
+
return animateNow($element, translateCss(travelDistance, 0), options);
|
8519
8953
|
});
|
8520
|
-
registerAnimation('move-from-right', function($
|
8954
|
+
registerAnimation('move-from-right', function($element, options) {
|
8521
8955
|
var box, travelDistance;
|
8522
|
-
|
8523
|
-
box = u.measure($
|
8956
|
+
u.writeInlineStyle($element, translateCss(0, 0));
|
8957
|
+
box = u.measure($element);
|
8524
8958
|
travelDistance = u.clientSize().width - box.left;
|
8525
|
-
|
8526
|
-
return
|
8959
|
+
u.writeInlineStyle($element, translateCss(travelDistance, 0));
|
8960
|
+
return animateNow($element, translateCss(0, 0), options);
|
8527
8961
|
});
|
8528
|
-
registerAnimation('roll-down', function($
|
8962
|
+
registerAnimation('roll-down', function($element, options) {
|
8529
8963
|
var deferred, fullHeight, styleMemo;
|
8530
|
-
fullHeight = $
|
8531
|
-
styleMemo = u.
|
8964
|
+
fullHeight = $element.height();
|
8965
|
+
styleMemo = u.writeTemporaryStyle($element, {
|
8532
8966
|
height: '0px',
|
8533
8967
|
overflow: 'hidden'
|
8534
8968
|
});
|
8535
|
-
deferred = animate($
|
8969
|
+
deferred = animate($element, {
|
8536
8970
|
height: fullHeight + "px"
|
8537
8971
|
}, options);
|
8538
8972
|
deferred.then(styleMemo);
|
8539
8973
|
return deferred;
|
8540
8974
|
});
|
8541
|
-
registerTransition('move-left', 'move-to-left
|
8542
|
-
registerTransition('move-right', 'move-to-right
|
8543
|
-
registerTransition('move-up', 'move-to-top
|
8544
|
-
registerTransition('move-down', 'move-to-bottom
|
8545
|
-
registerTransition('cross-fade', 'fade-out
|
8975
|
+
registerTransition('move-left', ['move-to-left', 'move-from-right']);
|
8976
|
+
registerTransition('move-right', ['move-to-right', 'move-from-left']);
|
8977
|
+
registerTransition('move-up', ['move-to-top', 'move-from-bottom']);
|
8978
|
+
registerTransition('move-down', ['move-to-bottom', 'move-from-top']);
|
8979
|
+
registerTransition('cross-fade', ['fade-out', 'fade-in']);
|
8546
8980
|
up.on('up:framework:booted', snapshot);
|
8547
8981
|
up.on('up:framework:reset', reset);
|
8548
8982
|
return {
|
@@ -8551,11 +8985,13 @@ You can define custom animations using [`up.transition()`](/up.transition) and
|
|
8551
8985
|
animateOptions: animateOptions,
|
8552
8986
|
willAnimate: willAnimate,
|
8553
8987
|
finish: finish,
|
8988
|
+
finishCount: function() {
|
8989
|
+
return motionTracker.finishCount;
|
8990
|
+
},
|
8554
8991
|
transition: registerTransition,
|
8555
8992
|
animation: registerAnimation,
|
8556
8993
|
config: config,
|
8557
8994
|
isEnabled: isEnabled,
|
8558
|
-
prependCopy: prependCopy,
|
8559
8995
|
isNone: isNone
|
8560
8996
|
};
|
8561
8997
|
})(jQuery);
|
@@ -9583,11 +10019,19 @@ new page is loading.
|
|
9583
10019
|
}
|
9584
10020
|
};
|
9585
10021
|
shouldProcessEvent = function(event, $link) {
|
9586
|
-
var $
|
9587
|
-
|
9588
|
-
|
9589
|
-
|
9590
|
-
|
10022
|
+
var $betterTarget, target;
|
10023
|
+
target = event.target;
|
10024
|
+
if (!u.isUnmodifiedMouseEvent(event)) {
|
10025
|
+
return false;
|
10026
|
+
}
|
10027
|
+
if (target === $link.get(0)) {
|
10028
|
+
return true;
|
10029
|
+
}
|
10030
|
+
$betterTarget = $(target).closest("a, [up-href], " + (up.form.fieldSelector())).not($link);
|
10031
|
+
if ($betterTarget.length) {
|
10032
|
+
return false;
|
10033
|
+
}
|
10034
|
+
return true;
|
9591
10035
|
};
|
9592
10036
|
|
9593
10037
|
/***
|
@@ -9969,7 +10413,7 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
9969
10413
|
@internal
|
9970
10414
|
*/
|
9971
10415
|
fieldSelector = function() {
|
9972
|
-
return
|
10416
|
+
return config.fields.join(',');
|
9973
10417
|
};
|
9974
10418
|
|
9975
10419
|
/***
|
@@ -10211,7 +10655,7 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
10211
10655
|
}
|
10212
10656
|
delay = u.option(u.presentAttr($element, 'up-delay'), options.delay, config.observeDelay);
|
10213
10657
|
delay = parseInt(delay);
|
10214
|
-
$fields =
|
10658
|
+
$fields = u.selectInSubtree($element, fieldSelector());
|
10215
10659
|
destructors = u.map($fields, function(field) {
|
10216
10660
|
return observeField($(field), delay, callback);
|
10217
10661
|
});
|
@@ -10774,6 +11218,28 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
10774
11218
|
A CSS selector for elements whose visibility depends on this field's value.
|
10775
11219
|
@stable
|
10776
11220
|
*/
|
11221
|
+
|
11222
|
+
/***
|
11223
|
+
Only shows this element if an input field with [`[up-switch]`](/input-up-switch) has one of the given values.
|
11224
|
+
|
11225
|
+
See [`input[up-switch]`](/input-up-switch) for more documentation and examples.
|
11226
|
+
|
11227
|
+
@selector [up-show-for]
|
11228
|
+
@param {string} [up-show-for]
|
11229
|
+
A space-separated list of input values for which this element should be shown.
|
11230
|
+
@stable
|
11231
|
+
*/
|
11232
|
+
|
11233
|
+
/***
|
11234
|
+
Hides this element if an input field with [`[up-switch]`](/input-up-switch) has one of the given values.
|
11235
|
+
|
11236
|
+
See [`input[up-switch]`](/input-up-switch) for more documentation and examples.
|
11237
|
+
|
11238
|
+
@selector [up-hide-for]
|
11239
|
+
@param {string} [up-hide-for]
|
11240
|
+
A space-separated list of input values for which this element should be hidden.
|
11241
|
+
@stable
|
11242
|
+
*/
|
10777
11243
|
up.compiler('[up-switch]', function($field) {
|
10778
11244
|
return switchTargets($field);
|
10779
11245
|
});
|
@@ -10906,6 +11372,11 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
10906
11372
|
up.compiler('[up-autosubmit]', function($formOrField) {
|
10907
11373
|
return autosubmit($formOrField);
|
10908
11374
|
});
|
11375
|
+
up.compiler('[autofocus]', {
|
11376
|
+
batch: true
|
11377
|
+
}, function($input) {
|
11378
|
+
return $input.last().focus();
|
11379
|
+
});
|
10909
11380
|
up.on('up:framework:reset', reset);
|
10910
11381
|
return {
|
10911
11382
|
config: config,
|
@@ -11058,37 +11529,37 @@ The HTML of a popup element is simply this:
|
|
11058
11529
|
return config.reset();
|
11059
11530
|
};
|
11060
11531
|
align = function() {
|
11061
|
-
var
|
11062
|
-
|
11532
|
+
var linkBox, popupBox, style;
|
11533
|
+
style = {};
|
11063
11534
|
popupBox = u.measure(state.$popup);
|
11064
11535
|
if (u.isFixed(state.$anchor)) {
|
11065
11536
|
linkBox = state.$anchor.get(0).getBoundingClientRect();
|
11066
|
-
|
11537
|
+
style.position = 'fixed';
|
11067
11538
|
} else {
|
11068
11539
|
linkBox = u.measure(state.$anchor);
|
11069
11540
|
}
|
11070
11541
|
switch (state.position) {
|
11071
11542
|
case 'bottom-right':
|
11072
|
-
|
11073
|
-
|
11543
|
+
style.top = linkBox.top + linkBox.height;
|
11544
|
+
style.left = linkBox.left + linkBox.width - popupBox.width;
|
11074
11545
|
break;
|
11075
11546
|
case 'bottom-left':
|
11076
|
-
|
11077
|
-
|
11547
|
+
style.top = linkBox.top + linkBox.height;
|
11548
|
+
style.left = linkBox.left;
|
11078
11549
|
break;
|
11079
11550
|
case 'top-right':
|
11080
|
-
|
11081
|
-
|
11551
|
+
style.top = linkBox.top - popupBox.height;
|
11552
|
+
style.left = linkBox.left + linkBox.width - popupBox.width;
|
11082
11553
|
break;
|
11083
11554
|
case 'top-left':
|
11084
|
-
|
11085
|
-
|
11555
|
+
style.top = linkBox.top - popupBox.height;
|
11556
|
+
style.left = linkBox.left;
|
11086
11557
|
break;
|
11087
11558
|
default:
|
11088
11559
|
up.fail("Unknown position option '%s'", state.position);
|
11089
11560
|
}
|
11090
11561
|
state.$popup.attr('up-position', state.position);
|
11091
|
-
return state.$popup
|
11562
|
+
return u.writeInlineStyle(state.$popup, style);
|
11092
11563
|
};
|
11093
11564
|
discardHistory = function() {
|
11094
11565
|
state.coveredTitle = null;
|
@@ -11308,7 +11779,7 @@ The HTML of a popup element is simply this:
|
|
11308
11779
|
return attachNow($link, options);
|
11309
11780
|
};
|
11310
11781
|
toggleAsap = function($link, options) {
|
11311
|
-
if ($link
|
11782
|
+
if (u.hasClass($link, 'up-current')) {
|
11312
11783
|
return closeAsap();
|
11313
11784
|
} else {
|
11314
11785
|
return attachAsap($link, options);
|
@@ -11707,22 +12178,15 @@ or function.
|
|
11707
12178
|
return state.coveredUrl = null;
|
11708
12179
|
};
|
11709
12180
|
createHiddenFrame = function(target, options) {
|
11710
|
-
var $content, $dialog, $modal;
|
12181
|
+
var $content, $dialog, $modal, dialogStyles;
|
11711
12182
|
$modal = $(templateHtml());
|
11712
12183
|
$modal.attr('up-flavor', state.flavor);
|
11713
12184
|
if (u.isPresent(state.position)) {
|
11714
12185
|
$modal.attr('up-position', state.position);
|
11715
12186
|
}
|
11716
12187
|
$dialog = $modal.find('.up-modal-dialog');
|
11717
|
-
|
11718
|
-
|
11719
|
-
}
|
11720
|
-
if (u.isPresent(options.maxWidth)) {
|
11721
|
-
$dialog.css('max-width', options.maxWidth);
|
11722
|
-
}
|
11723
|
-
if (u.isPresent(options.height)) {
|
11724
|
-
$dialog.css('height', options.height);
|
11725
|
-
}
|
12188
|
+
dialogStyles = u.only(options, 'width', 'maxWidth', 'height');
|
12189
|
+
u.writeInlineStyle($dialog, dialogStyles);
|
11726
12190
|
if (!state.closable) {
|
11727
12191
|
$modal.find('.up-modal-close').remove();
|
11728
12192
|
}
|
@@ -11740,20 +12204,20 @@ or function.
|
|
11740
12204
|
if (u.documentHasVerticalScrollbar()) {
|
11741
12205
|
$body = $('body');
|
11742
12206
|
scrollbarWidth = u.scrollbarWidth();
|
11743
|
-
bodyRightPadding =
|
12207
|
+
bodyRightPadding = u.readComputedStyleNumber($body, 'paddingRight');
|
11744
12208
|
bodyRightShift = scrollbarWidth + bodyRightPadding;
|
11745
|
-
unshiftBody = u.
|
11746
|
-
|
11747
|
-
|
12209
|
+
unshiftBody = u.writeTemporaryStyle($body, {
|
12210
|
+
paddingRight: bodyRightShift,
|
12211
|
+
overflowY: 'hidden'
|
11748
12212
|
});
|
11749
12213
|
state.unshifters.push(unshiftBody);
|
11750
12214
|
return up.layout.anchoredRight().each(function() {
|
11751
12215
|
var $element, elementRight, elementRightShift, unshifter;
|
11752
12216
|
$element = $(this);
|
11753
|
-
elementRight =
|
12217
|
+
elementRight = u.readComputedStyleNumber($element, 'right');
|
11754
12218
|
elementRightShift = scrollbarWidth + elementRight;
|
11755
|
-
unshifter = u.
|
11756
|
-
|
12219
|
+
unshifter = u.writeTemporaryStyle($element, {
|
12220
|
+
right: elementRightShift
|
11757
12221
|
});
|
11758
12222
|
return state.unshifters.push(unshifter);
|
11759
12223
|
});
|
@@ -12459,37 +12923,37 @@ The tooltip element is appended to the end of `<body>`.
|
|
12459
12923
|
return config.reset();
|
12460
12924
|
};
|
12461
12925
|
align = function() {
|
12462
|
-
var
|
12463
|
-
|
12926
|
+
var linkBox, style, tooltipBox;
|
12927
|
+
style = {};
|
12464
12928
|
tooltipBox = u.measure(state.$tooltip);
|
12465
12929
|
if (u.isFixed(state.$anchor)) {
|
12466
12930
|
linkBox = state.$anchor.get(0).getBoundingClientRect();
|
12467
|
-
|
12931
|
+
style.position = 'fixed';
|
12468
12932
|
} else {
|
12469
12933
|
linkBox = u.measure(state.$anchor);
|
12470
12934
|
}
|
12471
12935
|
switch (state.position) {
|
12472
12936
|
case 'top':
|
12473
|
-
|
12474
|
-
|
12937
|
+
style.top = linkBox.top - tooltipBox.height;
|
12938
|
+
style.left = linkBox.left + 0.5 * (linkBox.width - tooltipBox.width);
|
12475
12939
|
break;
|
12476
12940
|
case 'left':
|
12477
|
-
|
12478
|
-
|
12941
|
+
style.top = linkBox.top + 0.5 * (linkBox.height - tooltipBox.height);
|
12942
|
+
style.left = linkBox.left - tooltipBox.width;
|
12479
12943
|
break;
|
12480
12944
|
case 'right':
|
12481
|
-
|
12482
|
-
|
12945
|
+
style.top = linkBox.top + 0.5 * (linkBox.height - tooltipBox.height);
|
12946
|
+
style.left = linkBox.left + linkBox.width;
|
12483
12947
|
break;
|
12484
12948
|
case 'bottom':
|
12485
|
-
|
12486
|
-
|
12949
|
+
style.top = linkBox.top + linkBox.height;
|
12950
|
+
style.left = linkBox.left + 0.5 * (linkBox.width - tooltipBox.width);
|
12487
12951
|
break;
|
12488
12952
|
default:
|
12489
12953
|
up.fail("Unknown position option '%s'", state.position);
|
12490
12954
|
}
|
12491
12955
|
state.$tooltip.attr('up-position', state.position);
|
12492
|
-
return state.$tooltip
|
12956
|
+
return u.writeInlineStyle(state.$tooltip, style);
|
12493
12957
|
};
|
12494
12958
|
createElement = function(options) {
|
12495
12959
|
var $element;
|
@@ -12678,12 +13142,13 @@ The tooltip element is appended to the end of `<body>`.
|
|
12678
13142
|
Navigation feedback
|
12679
13143
|
===================
|
12680
13144
|
|
12681
|
-
Unpoly automatically adds
|
12682
|
-
currently loading ([`.up-active`](/a.up-active)) or
|
12683
|
-
pointing to the current location ([`.up-current`](/a.up-current)).
|
13145
|
+
Unpoly automatically adds the class [`.up-active`](/a.up-active) to links or forms while they are loading.
|
12684
13146
|
|
12685
|
-
By
|
12686
|
-
|
13147
|
+
By marking navigation elements as [`[up-nav]`](/up-nav), contained links that point to the current location
|
13148
|
+
automatically get the [`.up-current`](/up-nav-a.up-current) class.
|
13149
|
+
|
13150
|
+
You should style [`.up-active`](/a.up-active) and [`.up-current`](/up-nav a.up-current) with CSS to
|
13151
|
+
provide instant feedback to user interactions. This improves the perceived speed of your interface.
|
12687
13152
|
|
12688
13153
|
\#\#\# Example
|
12689
13154
|
|
@@ -12716,7 +13181,7 @@ Once the response is received the URL will change to `/bar` and the `up-active`
|
|
12716
13181
|
var slice = [].slice;
|
12717
13182
|
|
12718
13183
|
up.feedback = (function($) {
|
12719
|
-
var CLASS_ACTIVE,
|
13184
|
+
var CLASS_ACTIVE, NORMALIZED_SECTION_URLS_KEY, SELECTOR_LINK, buildCurrentUrlSet, buildSectionUrls, config, currentUrlSet, findActivatableArea, navSelector, normalizeUrl, previousUrlSet, reset, sectionUrls, start, stop, u, updateAllNavigationSections, updateAllNavigationSectionsIfLocationChanged, updateCurrentClassForLinks, updateNavigationSectionsInNewFragment;
|
12720
13185
|
u = up.util;
|
12721
13186
|
|
12722
13187
|
/***
|
@@ -12725,23 +13190,26 @@ Once the response is received the URL will change to `/bar` and the `up-active`
|
|
12725
13190
|
@property up.feedback.config
|
12726
13191
|
@param {Array<string>} [config.currentClasses]
|
12727
13192
|
An array of classes to set on [links that point the current location](/a.up-current).
|
13193
|
+
@param {Array<string>} [config.navs]
|
13194
|
+
An array of CSS selectors that match [navigation components](/up-nav).
|
12728
13195
|
@stable
|
12729
13196
|
*/
|
12730
13197
|
config = u.config({
|
12731
|
-
currentClasses: ['up-current']
|
13198
|
+
currentClasses: ['up-current'],
|
13199
|
+
navs: ['[up-nav]']
|
12732
13200
|
});
|
13201
|
+
previousUrlSet = void 0;
|
13202
|
+
currentUrlSet = void 0;
|
12733
13203
|
reset = function() {
|
12734
|
-
|
12735
|
-
|
12736
|
-
|
12737
|
-
var classes;
|
12738
|
-
classes = config.currentClasses;
|
12739
|
-
classes = classes.concat(['up-current']);
|
12740
|
-
classes = u.uniq(classes);
|
12741
|
-
return classes.join(' ');
|
13204
|
+
config.reset();
|
13205
|
+
previousUrlSet = void 0;
|
13206
|
+
return currentUrlSet = void 0;
|
12742
13207
|
};
|
12743
13208
|
CLASS_ACTIVE = 'up-active';
|
12744
|
-
|
13209
|
+
SELECTOR_LINK = 'a, [up-href]';
|
13210
|
+
navSelector = function() {
|
13211
|
+
return config.navs.join(',');
|
13212
|
+
};
|
12745
13213
|
normalizeUrl = function(url) {
|
12746
13214
|
if (u.isPresent(url)) {
|
12747
13215
|
return u.normalizeUrl(url, {
|
@@ -12749,77 +13217,102 @@ Once the response is received the URL will change to `/bar` and the `up-active`
|
|
12749
13217
|
});
|
12750
13218
|
}
|
12751
13219
|
};
|
13220
|
+
NORMALIZED_SECTION_URLS_KEY = 'up-normalized-urls';
|
12752
13221
|
sectionUrls = function($section) {
|
12753
|
-
var
|
13222
|
+
var urls;
|
13223
|
+
if (!(urls = $section.data(NORMALIZED_SECTION_URLS_KEY))) {
|
13224
|
+
urls = buildSectionUrls($section);
|
13225
|
+
$section.data(NORMALIZED_SECTION_URLS_KEY, urls);
|
13226
|
+
}
|
13227
|
+
return urls;
|
13228
|
+
};
|
13229
|
+
buildSectionUrls = function($section) {
|
13230
|
+
var attr, i, j, len, len1, ref, ref1, url, urls, value;
|
12754
13231
|
urls = [];
|
12755
|
-
|
12756
|
-
|
12757
|
-
|
12758
|
-
|
12759
|
-
|
12760
|
-
|
12761
|
-
|
12762
|
-
|
12763
|
-
url
|
12764
|
-
|
13232
|
+
if (up.link.isSafe($section)) {
|
13233
|
+
ref = ['href', 'up-href', 'up-alias'];
|
13234
|
+
for (i = 0, len = ref.length; i < len; i++) {
|
13235
|
+
attr = ref[i];
|
13236
|
+
if (value = u.presentAttr($section, attr)) {
|
13237
|
+
ref1 = value.split(/\s+/);
|
13238
|
+
for (j = 0, len1 = ref1.length; j < len1; j++) {
|
13239
|
+
url = ref1[j];
|
13240
|
+
if (url !== '#') {
|
13241
|
+
url = normalizeUrl(url);
|
13242
|
+
urls.push(url);
|
13243
|
+
}
|
12765
13244
|
}
|
12766
13245
|
}
|
12767
13246
|
}
|
12768
13247
|
}
|
12769
13248
|
return urls;
|
12770
13249
|
};
|
12771
|
-
|
12772
|
-
var
|
12773
|
-
urls =
|
12774
|
-
|
12775
|
-
|
12776
|
-
|
12777
|
-
|
12778
|
-
|
12779
|
-
|
12780
|
-
|
12781
|
-
|
12782
|
-
|
12783
|
-
|
12784
|
-
|
12785
|
-
|
12786
|
-
|
12787
|
-
|
12788
|
-
|
12789
|
-
|
12790
|
-
matchesAny = function(testUrls) {
|
12791
|
-
return u.detect(testUrls, matches);
|
12792
|
-
};
|
12793
|
-
return {
|
12794
|
-
matchesAny: matchesAny
|
12795
|
-
};
|
13250
|
+
buildCurrentUrlSet = function() {
|
13251
|
+
var urls;
|
13252
|
+
urls = [up.browser.url(), up.modal.url(), up.modal.coveredUrl(), up.popup.url(), up.popup.coveredUrl()];
|
13253
|
+
return new up.UrlSet(urls, {
|
13254
|
+
normalizeUrl: normalizeUrl
|
13255
|
+
});
|
13256
|
+
};
|
13257
|
+
updateAllNavigationSectionsIfLocationChanged = function() {
|
13258
|
+
previousUrlSet = currentUrlSet;
|
13259
|
+
currentUrlSet = buildCurrentUrlSet();
|
13260
|
+
if (!currentUrlSet.isEqual(previousUrlSet)) {
|
13261
|
+
return updateAllNavigationSections($('body'));
|
13262
|
+
}
|
13263
|
+
};
|
13264
|
+
updateAllNavigationSections = function($root) {
|
13265
|
+
var $navs, $sections;
|
13266
|
+
$navs = u.selectInSubtree($root, navSelector());
|
13267
|
+
$sections = u.selectInSubtree($navs, SELECTOR_LINK);
|
13268
|
+
return updateCurrentClassForLinks($sections);
|
12796
13269
|
};
|
12797
|
-
|
12798
|
-
var
|
12799
|
-
|
12800
|
-
|
12801
|
-
|
12802
|
-
|
12803
|
-
|
12804
|
-
|
12805
|
-
|
12806
|
-
|
12807
|
-
|
12808
|
-
|
13270
|
+
updateNavigationSectionsInNewFragment = function($fragment) {
|
13271
|
+
var $sections;
|
13272
|
+
if ($fragment.closest(navSelector()).length) {
|
13273
|
+
$sections = u.selectInSubtree($fragment, SELECTOR_LINK);
|
13274
|
+
return updateCurrentClassForLinks($sections);
|
13275
|
+
} else {
|
13276
|
+
return updateAllNavigationSections($fragment);
|
13277
|
+
}
|
13278
|
+
};
|
13279
|
+
updateCurrentClassForLinks = function($links) {
|
13280
|
+
currentUrlSet || (currentUrlSet = buildCurrentUrlSet());
|
13281
|
+
return u.each($links, function(link) {
|
13282
|
+
var $link, classList, i, j, klass, len, len1, ref, ref1, results, results1, urls;
|
13283
|
+
$link = $(link);
|
13284
|
+
urls = sectionUrls($link);
|
13285
|
+
classList = link.classList;
|
13286
|
+
if (currentUrlSet.matchesAny(urls)) {
|
13287
|
+
ref = config.currentClasses;
|
13288
|
+
results = [];
|
13289
|
+
for (i = 0, len = ref.length; i < len; i++) {
|
13290
|
+
klass = ref[i];
|
13291
|
+
results.push(classList.add(klass));
|
13292
|
+
}
|
13293
|
+
return results;
|
13294
|
+
} else {
|
13295
|
+
ref1 = config.currentClasses;
|
13296
|
+
results1 = [];
|
13297
|
+
for (j = 0, len1 = ref1.length; j < len1; j++) {
|
13298
|
+
klass = ref1[j];
|
13299
|
+
results1.push(classList.remove(klass));
|
13300
|
+
}
|
13301
|
+
return results1;
|
12809
13302
|
}
|
12810
13303
|
});
|
12811
13304
|
};
|
12812
13305
|
|
12813
13306
|
/***
|
12814
|
-
@function
|
13307
|
+
@function findActivatableArea
|
12815
13308
|
@param {string|Element|jQuery} elementOrSelector
|
12816
13309
|
@internal
|
12817
13310
|
*/
|
12818
|
-
|
13311
|
+
findActivatableArea = function(elementOrSelector) {
|
12819
13312
|
var $area;
|
12820
13313
|
$area = $(elementOrSelector);
|
12821
|
-
if ($area.is(
|
12822
|
-
$area = u.presence($area.parent(
|
13314
|
+
if ($area.is(SELECTOR_LINK)) {
|
13315
|
+
$area = u.presence($area.parent(SELECTOR_LINK)) || $area;
|
12823
13316
|
}
|
12824
13317
|
return $area;
|
12825
13318
|
};
|
@@ -12860,7 +13353,7 @@ Once the response is received the URL will change to `/bar` and the `up-active`
|
|
12860
13353
|
elementOrSelector = args.shift();
|
12861
13354
|
action = args.pop();
|
12862
13355
|
options = u.options(args[0]);
|
12863
|
-
$element =
|
13356
|
+
$element = findActivatableArea(elementOrSelector);
|
12864
13357
|
if (!options.preload) {
|
12865
13358
|
$element.addClass(CLASS_ACTIVE);
|
12866
13359
|
}
|
@@ -12949,40 +13442,58 @@ Once the response is received the URL will change to `/bar` and the `up-active`
|
|
12949
13442
|
*/
|
12950
13443
|
stop = function(elementOrSelector) {
|
12951
13444
|
var $element;
|
12952
|
-
$element =
|
13445
|
+
$element = findActivatableArea(elementOrSelector);
|
12953
13446
|
return $element.removeClass(CLASS_ACTIVE);
|
12954
13447
|
};
|
12955
13448
|
|
12956
13449
|
/***
|
12957
|
-
|
12958
|
-
|
13450
|
+
Marks this element as a navigation component, such as a menu or navigation bar.
|
13451
|
+
|
13452
|
+
When a link within an `[up-nav]` element points to the current location, it is assigned the `.up-current` class. When the browser navigates to another location, the class is removed automatically.
|
13453
|
+
|
13454
|
+
You may also assign `[up-nav]` to an individual link instead of an navigational container.
|
13455
|
+
|
13456
|
+
If you don't want to manually add this attribute to every navigational element, you can configure selectors to automatically match your navigation components in [`up.feedback.config.navs`](/up.feedback.config#config.navs).
|
13457
|
+
|
12959
13458
|
|
12960
|
-
|
13459
|
+
\#\#\# Example
|
13460
|
+
|
13461
|
+
Let's take a simple menu with two links. The menu has been marked with the `[up-nav]` attribute:
|
12961
13462
|
|
12962
|
-
<nav>
|
13463
|
+
<div up-nav>
|
12963
13464
|
<a href="/foo">Foo</a>
|
12964
13465
|
<a href="/bar">Bar</a>
|
12965
|
-
</
|
13466
|
+
</div>
|
12966
13467
|
|
12967
|
-
If the browser location changes to `/foo`, the
|
13468
|
+
If the browser location changes to `/foo`, the first link is marked as `.up-current`:
|
12968
13469
|
|
12969
|
-
<nav>
|
13470
|
+
<div up-nav>
|
12970
13471
|
<a href="/foo" class="up-current">Foo</a>
|
12971
13472
|
<a href="/bar">Bar</a>
|
12972
|
-
</
|
13473
|
+
</div>
|
13474
|
+
|
13475
|
+
If the browser location changes to `/bar`, the first link automatically loses its `.up-current` class. Now the second link is marked as `.up-current`:
|
13476
|
+
|
13477
|
+
<div up-nav>
|
13478
|
+
<a href="/foo">Foo</a>
|
13479
|
+
<a href="/bar" class="up-current">Bar</a>
|
13480
|
+
</div>
|
12973
13481
|
|
12974
|
-
|
13482
|
+
|
13483
|
+
\#\#\# What is considered to be "current"?
|
12975
13484
|
|
12976
13485
|
The current location is considered to be either:
|
12977
13486
|
|
12978
13487
|
- the URL displayed in the browser window's location bar
|
12979
|
-
- the source URL of a
|
12980
|
-
- the
|
13488
|
+
- the source URL of a [modal dialog](/up.modal)
|
13489
|
+
- the URL of the page behind a [modal dialog](/up.modal)
|
13490
|
+
- the source URL of a [popup overlay](/up.popup)
|
13491
|
+
- the URL of the content behind a [popup overlay](/up.popup)
|
12981
13492
|
|
12982
13493
|
A link matches the current location (and is marked as `.up-current`) if it matches either:
|
12983
13494
|
|
12984
13495
|
- the link's `href` attribute
|
12985
|
-
- the link's
|
13496
|
+
- the link's `up-href` attribute
|
12986
13497
|
- a space-separated list of URLs in the link's `up-alias` attribute
|
12987
13498
|
|
12988
13499
|
\#\#\# Matching URL by prefix
|
@@ -12990,20 +13501,27 @@ Once the response is received the URL will change to `/bar` and the `up-active`
|
|
12990
13501
|
You can mark a link as `.up-current` whenever the current URL matches a prefix.
|
12991
13502
|
To do so, end the `up-alias` attribute in an asterisk (`*`).
|
12992
13503
|
|
12993
|
-
For instance, the following link is highlighted for both `/reports` and `/reports/123`:
|
13504
|
+
For instance, the following `[up-nav]` link is highlighted for both `/reports` and `/reports/123`:
|
13505
|
+
|
13506
|
+
<a up-nav href="/reports" up-alias="/reports/*">Reports</a>
|
13507
|
+
|
13508
|
+
@selector [up-nav]
|
13509
|
+
@stable
|
13510
|
+
*/
|
13511
|
+
|
13512
|
+
/***
|
13513
|
+
When a link within an `[up-nav]` element points to the current location, it is assigned the `.up-current` class.
|
12994
13514
|
|
12995
|
-
|
13515
|
+
See [`[up-nav]`](/up-nav) for more documentation and examples.
|
12996
13516
|
|
12997
|
-
@selector a.up-current
|
13517
|
+
@selector [up-nav] a.up-current
|
12998
13518
|
@stable
|
12999
13519
|
*/
|
13000
|
-
up.on('up:
|
13001
|
-
return
|
13520
|
+
up.on('up:history:pushed up:history:replaced up:history:restored up:modal:opened up:modal:closed up:popup:opened up:popup:closed', function(event) {
|
13521
|
+
return updateAllNavigationSectionsIfLocationChanged();
|
13002
13522
|
});
|
13003
|
-
up.on('up:fragment:
|
13004
|
-
|
13005
|
-
return locationChanged();
|
13006
|
-
}
|
13523
|
+
up.on('up:fragment:inserted', function(event, $newFragment) {
|
13524
|
+
return updateNavigationSectionsInNewFragment($newFragment);
|
13007
13525
|
});
|
13008
13526
|
up.on('up:framework:reset', reset);
|
13009
13527
|
return {
|
@@ -13061,7 +13579,7 @@ passively receive updates from the server.
|
|
13061
13579
|
@internal
|
13062
13580
|
*/
|
13063
13581
|
hungrySelector = function() {
|
13064
|
-
return
|
13582
|
+
return config.hungry.join(',');
|
13065
13583
|
};
|
13066
13584
|
|
13067
13585
|
/***
|