unpoly-rails 0.25.2 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of unpoly-rails might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e05bdbf4f5a4570761db4dcc4d60a492a9ef052d
4
- data.tar.gz: 563421cd51dd49c52bcd5d9d1fe18f24f1cd34c2
3
+ metadata.gz: 7039fd337b09cb3538de1a1d83b253689ff0cad7
4
+ data.tar.gz: e757bc24a9379ab5d9b6a6e9884718d75bf94ed5
5
5
  SHA512:
6
- metadata.gz: d9a21fabcc75e4cd98049c9a36f0978cc6d7c9077e16942c7ece8cb510ec01a22d33be0f7885bb9da605aebf06a68d2b4b60801d2fef3cadb498926238abbca2
7
- data.tar.gz: 71c49a8bbcd0498910e8e1fa625fc302222fe99eb8679bc2cec25f001c9656608aa855a9944ee0629fac872329d0bf79a82f6af91692528fc5c551fa54f7b3df
6
+ metadata.gz: 4f11fe51e4a7541923d428336b6166b4d2c3a43d00da245731048e89d50edd15fe3bf8bad05724629ce249c8f5c08b7aea62b76a5e0f0c6aa9867793a7ebf76b
7
+ data.tar.gz: 82190a7430b26ce7e0c73fd0b177c36931dd7344e7e48054aa05adb83b74dc32566b75a8efa171c6096aef856a762f40d594658ecf58e214335b6f7a30ea4973
data/CHANGELOG.md CHANGED
@@ -10,10 +10,29 @@ Unreleased
10
10
 
11
11
  ### Compatible changes
12
12
 
13
+
13
14
  ### Breaking changes
14
15
 
15
16
 
16
17
 
18
+ 0.26.0
19
+ ------
20
+
21
+ ### Compatible changes
22
+
23
+ - [Popups](/up.popup) no longer scroll with the document if they are attached to an element with `position: fixed`
24
+ - [Tooltips](/up.tooltip) no longer flicker if an [`[up-tooltip]`](/up-tooltip) elements has children
25
+ - [Tooltips](/up.tooltip) no longer flicker if the user moves the mouse too close to the tooltip triangle
26
+ - Before [compiling](/up.compile) the body, Unpoly now explicitly waits until user-provided compiles have been registered and the DOM is ready.
27
+ - Debugging messages in the developer console are now disabled by default. Call [`up.log.enable()`](/up.log.enable) to get them back.
28
+ - New configuration options in [`up.log.config`](/up.log.config): `up.log.config.enabled`, `up.log.config.collapse` and
29
+ `up.log.config.prefix`.
30
+ - Improve formatting of error messages.
31
+ - New experimental utility function [`up.util.escapeHtml`](/up.util.escapeHtml).
32
+ - If an error is thrown before the document is ready, Unpoly now waits until the document is ready before showing the red error box.
33
+
34
+
35
+
17
36
  0.25.2
18
37
  ------
19
38
 
data/dist/unpoly.css CHANGED
@@ -1,19 +1,26 @@
1
1
  [up-close] {
2
2
  cursor: pointer; }
3
3
  .up-error {
4
- background-color: #e10;
4
+ background-color: #c30;
5
5
  color: white;
6
- padding: 5px;
6
+ padding: 10px;
7
7
  font-family: arial, helvetica, sans-serif;
8
- font-weight: bold;
9
8
  font-size: 14px;
10
9
  line-height: 18px;
11
10
  position: fixed;
12
11
  left: 0;
13
- top: 0;
12
+ bottom: 0;
14
13
  max-width: 100%;
15
14
  box-sizing: border-box;
16
15
  z-index: 99999999; }
16
+
17
+ .up-error-variable {
18
+ background-color: rgba(0, 0, 0, 0.3);
19
+ padding: 1px 3px;
20
+ border-radius: 2px;
21
+ font-weight: normal;
22
+ max-width: 100px;
23
+ overflow: hidden; }
17
24
  [up-href] {
18
25
  cursor: pointer; }
19
26
  .up-modal {
@@ -89,7 +96,8 @@
89
96
  background-color: #111;
90
97
  color: white;
91
98
  padding: 6px 9px;
92
- white-space: nowrap; }
99
+ white-space: nowrap;
100
+ pointer-events: none; }
93
101
  .up-tooltip:after {
94
102
  content: "";
95
103
  position: absolute;
@@ -101,27 +109,31 @@
101
109
  margin-top: -6px; }
102
110
  .up-tooltip[up-position=top]:after {
103
111
  border-top-color: #111;
104
- bottom: -16px;
112
+ border-bottom-width: 0;
113
+ bottom: -8px;
105
114
  left: 50%;
106
115
  margin-left: -8px; }
107
116
  .up-tooltip[up-position=left] {
108
117
  margin-left: -6px; }
109
118
  .up-tooltip[up-position=left]:after {
110
119
  border-left-color: #111;
111
- right: -16px;
120
+ border-right-width: 0;
121
+ right: -8px;
112
122
  top: 50%;
113
123
  margin-top: -8px; }
114
124
  .up-tooltip[up-position=right] {
115
125
  margin-left: 6px; }
116
126
  .up-tooltip[up-position=right]:after {
117
127
  border-right-color: #111;
118
- left: -16px;
128
+ border-left-width: 0;
129
+ left: -8px;
119
130
  top: 50%;
120
131
  margin-top: -8px; }
121
132
  .up-tooltip[up-position=bottom] {
122
133
  margin-top: 6px; }
123
134
  .up-tooltip[up-position=bottom]:after {
124
135
  border-bottom-color: #111;
125
- top: -16px;
136
+ border-top-width: 0;
137
+ top: -8px;
126
138
  left: 50%;
127
139
  margin-left: -8px; }
data/dist/unpoly.js CHANGED
@@ -4,7 +4,9 @@
4
4
  */
5
5
 
6
6
  (function() {
7
- window.up = {};
7
+ window.up = {
8
+ version: "0.26.0"
9
+ };
8
10
 
9
11
  }).call(this);
10
12
 
@@ -29,7 +31,7 @@ that might save you from loading something like [Underscore.js](http://underscor
29
31
  @function up.util.noop
30
32
  @experimental
31
33
  */
32
- var $createElementFromSelector, $createPlaceholder, ANIMATION_DEFERRED_KEY, all, any, appendRequestData, cache, castedAttr, clientSize, compact, config, contains, copy, copyAttributes, createElement, createElementFromHtml, cssAnimate, detect, documentHasVerticalScrollbar, each, error, escapePressed, except, extend, extractOptions, findWithSelf, finishCssAnimate, fixedToAbsolute, forceCompositing, forceRepaint, intersect, isArray, isBlank, isDeferred, isDefined, isDetached, isElement, isFormData, isFunction, isGiven, isHash, isJQuery, isMissing, isNull, isNumber, isObject, isPresent, isPromise, isStandardPort, isString, isUndefined, isUnmodifiedKeyEvent, isUnmodifiedMouseEvent, last, locationFromXhr, map, measure, memoize, merge, methodFromXhr, multiSelector, nextFrame, nonUpClasses, noop, normalizeMethod, normalizeUrl, nullJQuery, offsetParent, once, only, opacity, option, options, parseUrl, pluckData, pluckKey, presence, presentAttr, reject, remove, requestDataAsArray, requestDataAsQuery, requestDataFromForm, resolvableWhen, resolvedDeferred, resolvedPromise, scrollbarWidth, select, selectorForElement, setMissingAttrs, setTimer, temporaryCss, times, titleFromXhr, toArray, trim, unJQuery, uniq, unresolvableDeferred, unresolvablePromise, unwrapElement;
34
+ var $createElementFromSelector, $createPlaceholder, ANIMATION_DEFERRED_KEY, ESCAPE_HTML_ENTITY_MAP, all, any, appendRequestData, cache, castedAttr, clientSize, compact, config, contains, copy, copyAttributes, createElement, createElementFromHtml, cssAnimate, detect, documentHasVerticalScrollbar, each, error, escapeHtml, escapePressed, except, extend, extractOptions, findWithSelf, finishCssAnimate, fixedToAbsolute, forceCompositing, forceRepaint, identity, intersect, isArray, isBlank, isDeferred, isDefined, isDetached, isElement, isFixed, isFormData, isFunction, isGiven, isHash, isJQuery, isMissing, isNull, isNumber, isObject, isPresent, isPromise, isStandardPort, isString, isUndefined, isUnmodifiedKeyEvent, isUnmodifiedMouseEvent, last, locationFromXhr, map, measure, memoize, merge, methodFromXhr, multiSelector, nextFrame, nonUpClasses, noop, normalizeMethod, normalizeUrl, nullJQuery, offsetParent, once, only, opacity, option, options, parseUrl, pluckData, pluckKey, presence, presentAttr, reject, remove, requestDataAsArray, requestDataAsQuery, requestDataFromForm, resolvableWhen, resolvedDeferred, resolvedPromise, scrollbarWidth, select, selectorForElement, setMissingAttrs, setTimer, temporaryCss, times, titleFromXhr, toArray, trim, unJQuery, uniq, unresolvableDeferred, unresolvablePromise, unwrapElement, whenReady;
33
35
  noop = $.noop;
34
36
 
35
37
  /**
@@ -1790,6 +1792,28 @@ that might save you from loading something like [Underscore.js](http://underscor
1790
1792
  return $match;
1791
1793
  };
1792
1794
 
1795
+ /**
1796
+ Returns if the given element has a `fixed` position.
1797
+
1798
+ @function up.util.isFixed
1799
+ @internal
1800
+ */
1801
+ isFixed = function(element) {
1802
+ var $element, position;
1803
+ $element = $(element);
1804
+ while (true) {
1805
+ position = $element.css('position');
1806
+ if (position === 'fixed') {
1807
+ return true;
1808
+ } else {
1809
+ $element = $element.parent();
1810
+ if ($element.length === 0 || $element.is(document)) {
1811
+ return false;
1812
+ }
1813
+ }
1814
+ }
1815
+ };
1816
+
1793
1817
  /**
1794
1818
  @function up.util.fixedToAbsolute
1795
1819
  @internal
@@ -1932,15 +1956,41 @@ that might save you from loading something like [Underscore.js](http://underscor
1932
1956
  @experimental
1933
1957
  */
1934
1958
  error = function() {
1935
- var $error, args, asString, ref, ref1;
1959
+ var args, asString, ref, ref1;
1936
1960
  args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
1937
1961
  (ref = up.log).error.apply(ref, args);
1962
+ whenReady().then(function() {
1963
+ var $error, asHtml, formatter, ref1;
1964
+ $error = presence($('.up-error')) || $('<div class="up-error"></div>').prependTo('body');
1965
+ formatter = function(arg) {
1966
+ return "<span class='up-error-variable'>" + (escapeHtml(arg)) + "</span>";
1967
+ };
1968
+ asHtml = (ref1 = up.browser).sprintfWithFormattedArgs.apply(ref1, [formatter].concat(slice.call(args)));
1969
+ return $error.html(asHtml);
1970
+ });
1938
1971
  asString = (ref1 = up.browser).sprintf.apply(ref1, args);
1939
- $error = presence($('.up-error')) || $('<div class="up-error"></div>').prependTo('body');
1940
- $error.addClass('up-error');
1941
- $error.text(asString);
1942
1972
  throw new Error(asString);
1943
1973
  };
1974
+ ESCAPE_HTML_ENTITY_MAP = {
1975
+ "&": "&amp;",
1976
+ "<": "&lt;",
1977
+ ">": "&gt;",
1978
+ '"': '&quot;'
1979
+ };
1980
+
1981
+ /**
1982
+ Escapes the given string of HTML by replacing control chars with their HTML entities.
1983
+
1984
+ @function up.util.escapeHtml
1985
+ @param {String} string
1986
+ The text that should be escaped
1987
+ @experimental
1988
+ */
1989
+ escapeHtml = function(string) {
1990
+ return string.replace(/[&<>"]/g, function(char) {
1991
+ return ESCAPE_HTML_ENTITY_MAP[char];
1992
+ });
1993
+ };
1944
1994
  pluckKey = function(object, key) {
1945
1995
  var value;
1946
1996
  value = object[key];
@@ -1972,6 +2022,21 @@ that might save you from loading something like [Underscore.js](http://underscor
1972
2022
  return void 0;
1973
2023
  }
1974
2024
  };
2025
+ whenReady = memoize(function() {
2026
+ var deferred;
2027
+ if ($.isReady) {
2028
+ return resolvedPromise();
2029
+ } else {
2030
+ deferred = $.Deferred();
2031
+ $(function() {
2032
+ return deferred.resolve();
2033
+ });
2034
+ return deferred.promise();
2035
+ }
2036
+ });
2037
+ identity = function(arg) {
2038
+ return arg;
2039
+ };
1975
2040
 
1976
2041
  /**
1977
2042
  Returns whether the given element has been detached from the DOM
@@ -1992,6 +2057,7 @@ that might save you from loading something like [Underscore.js](http://underscor
1992
2057
  requestDataFromForm: requestDataFromForm,
1993
2058
  offsetParent: offsetParent,
1994
2059
  fixedToAbsolute: fixedToAbsolute,
2060
+ isFixed: isFixed,
1995
2061
  presentAttr: presentAttr,
1996
2062
  createElement: createElement,
1997
2063
  parseUrl: parseUrl,
@@ -2030,6 +2096,7 @@ that might save you from loading something like [Underscore.js](http://underscor
2030
2096
  isObject: isObject,
2031
2097
  isFunction: isFunction,
2032
2098
  isString: isString,
2099
+ isNumber: isNumber,
2033
2100
  isElement: isElement,
2034
2101
  isJQuery: isJQuery,
2035
2102
  isPromise: isPromise,
@@ -2082,7 +2149,10 @@ that might save you from loading something like [Underscore.js](http://underscor
2082
2149
  extractOptions: extractOptions,
2083
2150
  isDetached: isDetached,
2084
2151
  noop: noop,
2085
- opacity: opacity
2152
+ opacity: opacity,
2153
+ whenReady: whenReady,
2154
+ identity: identity,
2155
+ escapeHtml: escapeHtml
2086
2156
  };
2087
2157
  })($);
2088
2158
 
@@ -2090,117 +2160,6 @@ that might save you from loading something like [Underscore.js](http://underscor
2090
2160
 
2091
2161
  }).call(this);
2092
2162
 
2093
- /**
2094
- Logging
2095
- =======
2096
-
2097
- Elaborate wrappers around `window.console`.
2098
- Should only used internally since they prefix `ᴜᴘ` to each
2099
- printed message.
2100
- */
2101
-
2102
- (function() {
2103
- var slice = [].slice;
2104
-
2105
- up.log = (function($) {
2106
- var debug, error, group, prefix, puts, warn;
2107
- prefix = function(message) {
2108
- return "ᴜᴘ " + message;
2109
- };
2110
-
2111
- /**
2112
- Prints a debugging message to the browser console.
2113
-
2114
- @function up.debug
2115
- @param {String} message
2116
- @param {Array} args...
2117
- @internal
2118
- */
2119
- debug = function() {
2120
- var args, message, ref;
2121
- message = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
2122
- if (message) {
2123
- return (ref = up.browser).puts.apply(ref, ['debug', prefix(message)].concat(slice.call(args)));
2124
- }
2125
- };
2126
-
2127
- /**
2128
- Prints a logging message to the browser console.
2129
-
2130
- @function up.puts
2131
- @param {String} message
2132
- @param {Array} args...
2133
- @internal
2134
- */
2135
- puts = function() {
2136
- var args, message, ref;
2137
- message = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
2138
- if (message) {
2139
- return (ref = up.browser).puts.apply(ref, ['log', prefix(message)].concat(slice.call(args)));
2140
- }
2141
- };
2142
-
2143
- /**
2144
- @function up.log.warn
2145
- @internal
2146
- */
2147
- warn = function() {
2148
- var args, message, ref;
2149
- message = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
2150
- if (message) {
2151
- return (ref = up.browser).puts.apply(ref, ['warn', prefix(message)].concat(slice.call(args)));
2152
- }
2153
- };
2154
-
2155
- /**
2156
- - Makes sure the group always closes
2157
- - Does not make a group if the message is nil
2158
-
2159
- @function up.log.group
2160
- @internal
2161
- */
2162
- group = function() {
2163
- var args, block, message, ref;
2164
- message = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
2165
- block = args.pop();
2166
- if (message) {
2167
- (ref = up.browser).puts.apply(ref, ['group', prefix(message)].concat(slice.call(args)));
2168
- try {
2169
- return block();
2170
- } finally {
2171
- if (message) {
2172
- console.groupEnd();
2173
- }
2174
- }
2175
- } else {
2176
- return block();
2177
- }
2178
- };
2179
-
2180
- /**
2181
- @function up.log.error
2182
- @internal
2183
- */
2184
- error = function() {
2185
- var args, message, ref;
2186
- message = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
2187
- if (message) {
2188
- return (ref = up.browser).puts.apply(ref, ['error', prefix(message)].concat(slice.call(args)));
2189
- }
2190
- };
2191
- return {
2192
- puts: puts,
2193
- debug: debug,
2194
- error: error,
2195
- warn: warn,
2196
- group: group
2197
- };
2198
- })(jQuery);
2199
-
2200
- up.puts = up.log.puts;
2201
-
2202
- }).call(this);
2203
-
2204
2163
  /**
2205
2164
  Browser interface
2206
2165
  =================
@@ -2215,7 +2174,7 @@ we can't currently get rid off.
2215
2174
  var slice = [].slice;
2216
2175
 
2217
2176
  up.browser = (function($) {
2218
- var CONSOLE_PLACEHOLDERS, canCssTransition, canFormData, canInputEvent, canLogSubstitution, canPushState, confirm, initialRequestMethod, installPolyfills, isIE8OrWorse, isIE9OrWorse, isRecentJQuery, isSupported, loadPage, popCookie, puts, sprintf, u, url;
2177
+ var CONSOLE_PLACEHOLDERS, canCssTransition, canFormData, canInputEvent, canLogSubstitution, canPushState, confirm, initialRequestMethod, installPolyfills, isIE8OrWorse, isIE9OrWorse, isRecentJQuery, isSupported, loadPage, popCookie, puts, sprintf, sprintfWithFormattedArgs, stringifyArg, u, url;
2219
2178
  u = up.util;
2220
2179
 
2221
2180
  /**
@@ -2278,13 +2237,54 @@ we can't currently get rid off.
2278
2237
  stream = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
2279
2238
  u.isDefined(console[stream]) || (stream = 'log');
2280
2239
  if (canLogSubstitution()) {
2281
- return console[stream].apply(console, args);
2240
+ return typeof console[stream] === "function" ? console[stream].apply(console, args) : void 0;
2282
2241
  } else {
2283
2242
  message = sprintf.apply(null, args);
2284
- return console[stream](message);
2243
+ return typeof console[stream] === "function" ? console[stream](message) : void 0;
2285
2244
  }
2286
2245
  };
2287
2246
  CONSOLE_PLACEHOLDERS = /\%[odisf]/g;
2247
+ stringifyArg = function(arg) {
2248
+ var $arg, attr, closer, j, len, maxLength, ref, string, value;
2249
+ maxLength = 100;
2250
+ closer = '';
2251
+ if (u.isString(arg)) {
2252
+ string = arg.replace(/[\n\r\t ]+/g, ' ');
2253
+ string = string.replace(/^[\n\r\t ]+/, '');
2254
+ string = string.replace(/[\n\r\t ]$/, '');
2255
+ string = "\"" + string + "\"";
2256
+ closer = '"';
2257
+ } else if (u.isUndefined(arg)) {
2258
+ string = 'undefined';
2259
+ } else if (u.isNumber(arg) || u.isFunction(arg)) {
2260
+ string = arg.toString();
2261
+ } else if (u.isArray(arg)) {
2262
+ string = "[" + (u.map(arg, stringifyArg).join(', ')) + "]";
2263
+ closer = ']';
2264
+ } else if (u.isJQuery(arg)) {
2265
+ string = "$(" + (u.map(arg, stringifyArg).join(', ')) + ")";
2266
+ closer = ')';
2267
+ } else if (u.isElement(arg)) {
2268
+ $arg = $(arg);
2269
+ string = "<" + (arg.tagName.toLowerCase());
2270
+ ref = ['id', 'name', 'class'];
2271
+ for (j = 0, len = ref.length; j < len; j++) {
2272
+ attr = ref[j];
2273
+ if (value = $arg.attr(attr)) {
2274
+ string += " " + attr + "=\"" + value + "\"";
2275
+ }
2276
+ }
2277
+ string += ">";
2278
+ closer = '>';
2279
+ } else {
2280
+ string = JSON.stringify(arg);
2281
+ }
2282
+ if (string.length > maxLength) {
2283
+ string = (string.substr(0, maxLength)) + " …";
2284
+ string += closer;
2285
+ }
2286
+ return string;
2287
+ };
2288
2288
 
2289
2289
  /**
2290
2290
  See https://developer.mozilla.org/en-US/docs/Web/API/Console#Using_string_substitutions
@@ -2293,33 +2293,23 @@ we can't currently get rid off.
2293
2293
  @internal
2294
2294
  */
2295
2295
  sprintf = function() {
2296
- var args, i, maxLength, message;
2296
+ var args, message;
2297
2297
  message = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
2298
+ return sprintfWithFormattedArgs.apply(null, [u.identity, message].concat(slice.call(args)));
2299
+ };
2300
+
2301
+ /**
2302
+ @function up.browser.sprintfWithBounds
2303
+ @internal
2304
+ */
2305
+ sprintfWithFormattedArgs = function() {
2306
+ var args, formatter, i, message;
2307
+ formatter = arguments[0], message = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : [];
2298
2308
  i = 0;
2299
- maxLength = 80;
2300
2309
  return message.replace(CONSOLE_PLACEHOLDERS, function() {
2301
- var arg, argType;
2310
+ var arg;
2302
2311
  arg = args[i];
2303
- argType = typeof arg;
2304
- if (argType === 'string') {
2305
- arg = arg.replace(/\s+/g, ' ');
2306
- if (arg.length > maxLength) {
2307
- arg = (arg.substr(0, maxLength)) + "…";
2308
- }
2309
- arg = "\"" + arg + "\"";
2310
- } else if (argType === 'undefined') {
2311
- arg = 'undefined';
2312
- } else if (argType === 'number' || argType === 'function') {
2313
- arg = arg.toString();
2314
- } else {
2315
- arg = JSON.stringify(arg);
2316
- }
2317
- if (arg.length > maxLength) {
2318
- arg = (arg.substr(0, maxLength)) + " …";
2319
- if (argType === 'object' || argType === 'function') {
2320
- arg += " }";
2321
- }
2322
- }
2312
+ arg = formatter(stringifyArg(arg));
2323
2313
  i += 1;
2324
2314
  return arg;
2325
2315
  });
@@ -2492,7 +2482,8 @@ we can't currently get rid off.
2492
2482
  isSupported: isSupported,
2493
2483
  installPolyfills: installPolyfills,
2494
2484
  puts: puts,
2495
- sprintf: sprintf
2485
+ sprintf: sprintf,
2486
+ sprintfWithFormattedArgs: sprintfWithFormattedArgs
2496
2487
  };
2497
2488
  })(jQuery);
2498
2489
 
@@ -2902,7 +2893,7 @@ This improves jQuery's [`on`](http://api.jquery.com/on/) in multiple ways:
2902
2893
  @experimental
2903
2894
  */
2904
2895
  emitReset = function() {
2905
- return up.emit('up:framework:reset', {
2896
+ return emit('up:framework:reset', {
2906
2897
  message: 'Resetting framework'
2907
2898
  });
2908
2899
  };
@@ -2917,7 +2908,7 @@ This improves jQuery's [`on`](http://api.jquery.com/on/) in multiple ways:
2917
2908
  /**
2918
2909
  Boots the Unpoly framework.
2919
2910
 
2920
- This is done automatically by including the Unpoly Javascript.
2911
+ **This is called automatically** by including the Unpoly Javascript files.
2921
2912
 
2922
2913
  Unpoly will not boot if the current browser is [not supported](/up.browser.isSupported).
2923
2914
  This leaves you with a classic server-side application on legacy browsers.
@@ -2925,24 +2916,37 @@ This improves jQuery's [`on`](http://api.jquery.com/on/) in multiple ways:
2925
2916
  Emits the [`up:framework:boot`](/up:framework:boot) event.
2926
2917
 
2927
2918
  @function up.boot
2928
- @experimental
2919
+ @internal
2929
2920
  */
2930
2921
  boot = function() {
2931
2922
  if (up.browser.isSupported()) {
2932
2923
  up.browser.installPolyfills();
2933
- return up.emit('up:framework:boot', {
2924
+ emit('up:framework:boot', {
2934
2925
  message: 'Booting framework'
2935
2926
  });
2927
+ emit('up:framework:booted', {
2928
+ message: 'Framework booted'
2929
+ });
2930
+ return u.nextFrame(function() {
2931
+ return u.whenReady().then(function() {
2932
+ emit('up:app:boot', {
2933
+ message: 'Booting user application'
2934
+ });
2935
+ return emit('up:app:booted', {
2936
+ message: 'User application booted'
2937
+ });
2938
+ });
2939
+ });
2936
2940
  }
2937
2941
  };
2938
2942
 
2939
2943
  /**
2940
- This event is [emitted](/up.emit) when Unpoly [boots](/up.boot).
2944
+ This event is [emitted](/up.emit) when Unpoly [starts to boot](/up.boot).
2941
2945
 
2942
2946
  @event up:framework:boot
2943
- @experimental
2947
+ @internal
2944
2948
  */
2945
- live('up:framework:boot', snapshot);
2949
+ live('up:framework:booted', snapshot);
2946
2950
  live('up:framework:reset', restoreSnapshot);
2947
2951
  return {
2948
2952
  knife: eval(typeof Knife !== "undefined" && Knife !== null ? Knife.point : void 0),
@@ -2968,6 +2972,187 @@ This improves jQuery's [`on`](http://api.jquery.com/on/) in multiple ways:
2968
2972
 
2969
2973
  }).call(this);
2970
2974
 
2975
+ /**
2976
+ Logging
2977
+ =======
2978
+
2979
+ Elaborate wrappers around `window.console`.
2980
+ Should only used internally since they prefix `ᴜᴘ` to each
2981
+ printed message.
2982
+ */
2983
+
2984
+ (function() {
2985
+ var slice = [].slice;
2986
+
2987
+ up.log = (function($) {
2988
+ var config, debug, disable, enable, error, group, prefix, printBanner, puts, reset, u, warn;
2989
+ u = up.util;
2990
+
2991
+ /**
2992
+ Configures the logging output on the developer console.
2993
+
2994
+ @property up.log.config
2995
+ @param {Boolean} [options.enabled=false]
2996
+ Whether Unpoly will print debugging information to the developer console.
2997
+
2998
+ Debugging information includes which elements are being [compiled](/up.syntax)
2999
+ and which [events](/up.bus) are being emitted.
3000
+ Note that errors will always be printed, regardless of this setting.
3001
+ @param {Boolean} [options.collapse=false]
3002
+ Whether debugging information is printed as a collapsed tree.
3003
+
3004
+ Set this to `true` if you are overwhelmed by the debugging information Unpoly
3005
+ prints to the developer console.
3006
+ @param {String} [options.prefix='[UP] ']
3007
+ A string to prepend to Unpoly's logging messages so you can distinguish it from your own messages.
3008
+ @stable
3009
+ */
3010
+ config = u.config({
3011
+ prefix: '[UP] ',
3012
+ enabled: false,
3013
+ collapse: false
3014
+ });
3015
+ reset = function() {
3016
+ return config.reset();
3017
+ };
3018
+ prefix = function(message) {
3019
+ return "" + config.prefix + message;
3020
+ };
3021
+
3022
+ /**
3023
+ Prints a debugging message to the browser console.
3024
+
3025
+ @function up.debug
3026
+ @param {String} message
3027
+ @param {Array} args...
3028
+ @internal
3029
+ */
3030
+ debug = function() {
3031
+ var args, message, ref;
3032
+ message = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
3033
+ if (config.enabled && message) {
3034
+ return (ref = up.browser).puts.apply(ref, ['debug', prefix(message)].concat(slice.call(args)));
3035
+ }
3036
+ };
3037
+
3038
+ /**
3039
+ Prints a logging message to the browser console.
3040
+
3041
+ @function up.puts
3042
+ @param {String} message
3043
+ @param {Array} args...
3044
+ @internal
3045
+ */
3046
+ puts = function() {
3047
+ var args, message, ref;
3048
+ message = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
3049
+ if (config.enabled && message) {
3050
+ return (ref = up.browser).puts.apply(ref, ['log', prefix(message)].concat(slice.call(args)));
3051
+ }
3052
+ };
3053
+
3054
+ /**
3055
+ @function up.log.warn
3056
+ @internal
3057
+ */
3058
+ warn = function() {
3059
+ var args, message, ref;
3060
+ message = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
3061
+ if (config.enabled && message) {
3062
+ return (ref = up.browser).puts.apply(ref, ['warn', prefix(message)].concat(slice.call(args)));
3063
+ }
3064
+ };
3065
+
3066
+ /**
3067
+ - Makes sure the group always closes
3068
+ - Does not make a group if the message is nil
3069
+
3070
+ @function up.log.group
3071
+ @internal
3072
+ */
3073
+ group = function() {
3074
+ var args, block, message, ref, stream;
3075
+ message = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
3076
+ block = args.pop();
3077
+ if (config.enabled && message) {
3078
+ stream = config.collapse ? 'groupCollapsed' : 'group';
3079
+ (ref = up.browser).puts.apply(ref, [stream, prefix(message)].concat(slice.call(args)));
3080
+ try {
3081
+ return block();
3082
+ } finally {
3083
+ if (message) {
3084
+ console.groupEnd();
3085
+ }
3086
+ }
3087
+ } else {
3088
+ return block();
3089
+ }
3090
+ };
3091
+
3092
+ /**
3093
+ @function up.log.error
3094
+ @internal
3095
+ */
3096
+ error = function() {
3097
+ var args, message, ref;
3098
+ message = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
3099
+ if (message) {
3100
+ return (ref = up.browser).puts.apply(ref, ['error', prefix(message)].concat(slice.call(args)));
3101
+ }
3102
+ };
3103
+ printBanner = function() {
3104
+ var banner;
3105
+ banner = " __ _____ ___ ___ / /_ __\n" + ("/ // / _ \\/ _ \\/ _ \\/ / // / " + up.version + "\n") + "\\___/_//_/ .__/\\___/_/\\_. / \n" + " / / / /\n" + "\n";
3106
+ if (config.enabled) {
3107
+ banner += "Call `up.log.disable()` to disable debugging output.";
3108
+ } else {
3109
+ banner += "Call `up.log.enable()` to enable debugging output.";
3110
+ }
3111
+ return up.browser.puts('log', banner);
3112
+ };
3113
+ up.on('up:framework:boot', printBanner);
3114
+ up.on('up:framework:reset', reset);
3115
+
3116
+ /**
3117
+ Makes future Unpoly events print vast amounts of debugging information to the developer console.
3118
+
3119
+ Debugging information includes which elements are being [compiled](/up.syntax)
3120
+ and which [events](/up.bus) are being emitted.
3121
+
3122
+ @function up.log.enable
3123
+ @stable
3124
+ */
3125
+ enable = function() {
3126
+ return config.enabled = true;
3127
+ };
3128
+
3129
+ /**
3130
+ Prevents future Unpoly events from printing vast amounts of debugging information to the developer console.
3131
+
3132
+ Errors will still be printed.
3133
+
3134
+ @function up.log.enable
3135
+ @stable
3136
+ */
3137
+ disable = function() {
3138
+ return config.enabled = false;
3139
+ };
3140
+ return {
3141
+ puts: puts,
3142
+ debug: debug,
3143
+ error: error,
3144
+ warn: warn,
3145
+ group: group,
3146
+ config: config,
3147
+ enable: enable,
3148
+ disable: disable
3149
+ };
3150
+ })(jQuery);
3151
+
3152
+ up.puts = up.log.puts;
3153
+
3154
+ }).call(this);
3155
+
2971
3156
  /**
2972
3157
  Enhancing elements
2973
3158
  ==================
@@ -3465,7 +3650,7 @@ later.
3465
3650
  compilers = u.select(compilers, isDefault);
3466
3651
  return macros = u.select(macros, isDefault);
3467
3652
  };
3468
- up.on('up:framework:boot', snapshot);
3653
+ up.on('up:framework:booted', snapshot);
3469
3654
  up.on('up:framework:reset', reset);
3470
3655
  return {
3471
3656
  compiler: compiler,
@@ -5233,7 +5418,7 @@ are based on this module.
5233
5418
  sourceUrl = options.url || source(selectorOrElement);
5234
5419
  return replace(selectorOrElement, sourceUrl, options);
5235
5420
  };
5236
- up.on('ready', function() {
5421
+ up.on('up:app:boot', function() {
5237
5422
  var $body;
5238
5423
  $body = $(document.body);
5239
5424
  setSource($body, up.browser.url());
@@ -5967,7 +6152,7 @@ or [transitions](/up.transition) using Javascript or CSS.
5967
6152
  transition('cross-fade', function($old, $new, options) {
5968
6153
  return resolvableWhen(animate($old, 'fade-out', options), animate($new, 'fade-in', options));
5969
6154
  });
5970
- up.on('up:framework:boot', snapshot);
6155
+ up.on('up:framework:booted', snapshot);
5971
6156
  up.on('up:framework:reset', reset);
5972
6157
  return {
5973
6158
  morph: morph,
@@ -8191,6 +8376,9 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
8191
8376
  return u.error("Unknown position option '%s'", position);
8192
8377
  }
8193
8378
  })();
8379
+ if (u.isFixed($link)) {
8380
+ css['position'] = 'fixed';
8381
+ }
8194
8382
  $popup = $('.up-popup');
8195
8383
  $popup.attr('up-position', position);
8196
8384
  $popup.css(css);
@@ -9509,10 +9697,10 @@ The tooltip element is appended to the end of `<body>`.
9509
9697
  @stable
9510
9698
  */
9511
9699
  up.compiler('[up-tooltip], [up-tooltip-html]', function($link) {
9512
- $link.on('mouseover', function() {
9700
+ $link.on('mouseenter', function() {
9513
9701
  return attach($link);
9514
9702
  });
9515
- return $link.on('mouseout', function() {
9703
+ return $link.on('mouseleave', function() {
9516
9704
  return close();
9517
9705
  });
9518
9706
  });