unpoly-rails 2.0.0.pre.rc10 → 2.0.0.pre.rc11

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7bd5baa3c26dc137e7944861528cbacbd458d842c20ed3864e07840161a62662
4
- data.tar.gz: cbcf34505f475b8cbd062ab16081f49b98d904c027d0dfbd7c2a50c1871e0a09
3
+ metadata.gz: 16c5d23ef0ef94cd9a7cb5ef926ff4931aa1e2b19b32548c35b0fd527de83d91
4
+ data.tar.gz: 4748c57d0da382a24dd48f594ca3f61838387dc3fd3630da416843d8c45dc079
5
5
  SHA512:
6
- metadata.gz: f679fc7972c6149277d204609026039daa94a4f802dfc5fbb2ec5f4926c926b2f9befa524a3e6b5fc7c1c8b63388733a230b0e7059eea172dc9b5afeea2add21
7
- data.tar.gz: 122e0706cee0950c164dc5bf6aefc693edffa0e40218ae95037a13dacb7a1f911a9a5c04871c2e05b739a1cc47c958598ae384ed57a75bffad3c05124f872252
6
+ metadata.gz: 4b5ff85fee318e8200aef941b878d8bdac28872ff0a46e2e2468c3c28e883065daa30f96858418f900f6566632b0d469632ec8736cca550db2aa71c97fecacf0
7
+ data.tar.gz: 8f51f5822089f69e36da2a3c8cf7942bec84965014f0de1ebb524aaf13288697301e8fa68c747ee4b8d89a5e623eed5768bd904a87e0989ad0490527bdca2774
@@ -856,6 +856,11 @@ Returns the first descendant element matching the given selector.
856
856
  });
857
857
 
858
858
  }).call(this);
859
+
860
+ /***
861
+ @module up.layer
862
+ */
863
+
859
864
  (function() {
860
865
  var e, u;
861
866
 
@@ -1178,6 +1183,26 @@ This feature is now deprecated.
1178
1183
  (function() {
1179
1184
  up.migrate.renamedProperty(up.radio.config, 'hungry', 'hungrySelectors');
1180
1185
 
1186
+ }).call(this);
1187
+ (function() {
1188
+ var u;
1189
+
1190
+ u = up.util;
1191
+
1192
+ up.migrate.postCompile = function(elements, compiler) {
1193
+ var element, i, keepValue, len, results, value;
1194
+ if (keepValue = compiler.keep) {
1195
+ up.migrate.warn('The { keep: true } option for up.compiler() has been removed. Have the compiler set [up-keep] attribute instead.');
1196
+ value = u.isString(keepValue) ? keepValue : '';
1197
+ results = [];
1198
+ for (i = 0, len = elements.length; i < len; i++) {
1199
+ element = elements[i];
1200
+ results.push(element.setAttribute('up-keep', value));
1201
+ }
1202
+ return results;
1203
+ }
1204
+ };
1205
+
1181
1206
  }).call(this);
1182
1207
 
1183
1208
  /***
@@ -1 +1 @@
1
- (function(){up.framework.startExtension()}).call(this),function(){var u,p,e,t,r,a,n,i,o,l,c,s,d,m,g=[].slice;u=up.util,up.migrate=(p=new up.Config(function(){return{logLevel:"warn"}}),c=function(e,t,r){var a;return a=function(){return d("Property { %s } has been renamed to { %s } (found in %o)",t,r,e)},Object.defineProperty(e,t,{get:function(){return a(),this[r]},set:function(e){return a(),this[r]=e}})},a=function(e,t,r){if(u.isDefined(e[t]))return d("Property { %s } has been renamed to { %s } (found in %o)",t,r,e),u.renameKey(e,t,r)},o={},i=function(e,t){return o[e]=t},t=function(e){var t;return(t=o[e])?(d("Event "+e+" has been renamed to "+t),t):e},r=function(e){return u.uniq(u.map(e,t))},l=function(e,t){return Object.defineProperty(up,e,{get:function(){return d("up."+e+" has been renamed to up."+t),up[t]}})},m={},d=function(e){var t,r,a,n;if(a=e,t=2<=arguments.length?g.call(arguments,1):[],r=u.sprintf.apply(u,[a].concat(g.call(t))),!m[r])return m[r]=!0,(n=up.log)[p.logLevel].apply(n,["DEPRECATION",a].concat(g.call(t)))},e=function(e,t){return d(e+" has been deprecated. Use "+t+" instead.")},n=function(e){var t,r;return r=Promise.resolve(),t=r.then,r.then=function(){return d(e+" is now a sync function"),t.apply(this,arguments)},r},s=function(){return p.reset()},up.on("up:framework:reset",s),{deprecated:e,renamedPackage:l,renamedProperty:c,formerlyAsync:n,renamedEvent:i,fixEventTypes:r,fixKey:a,warn:d,loaded:!0,config:p})}.call(this),function(){var a=[].slice;up.util.only=function(e){var t,r;return r=e,t=2<=arguments.length?a.call(arguments,1):[],up.migrate.deprecated("up.util.only(object, ...keys)","up.util.pick(object, keys)"),up.util.pick(r,t)},up.util.except=function(e){var t,r;return r=e,t=2<=arguments.length?a.call(arguments,1):[],up.migrate.deprecated("up.util.except(object, ...keys)","up.util.omit(object, keys)"),up.util.omit(r,t)},up.util.parseUrl=function(){var e,t;return e=1<=arguments.length?a.call(arguments,0):[],up.migrate.warn("up.util.parseUrl() has been renamed to up.util.parseURL()"),(t=up.util).parseURL.apply(t,e)},up.util.any=function(){var e;return e=1<=arguments.length?a.call(arguments,0):[],up.migrate.warn("up.util.any() has been renamed to up.util.some()"),some.apply(null,e)},up.util.all=function(){var e,t;return e=1<=arguments.length?a.call(arguments,0):[],up.migrate.warn("up.util.all() has been renamed to up.util.every()"),(t=up.util).every.apply(t,e)},up.util.detect=function(){var e,t;return e=1<=arguments.length?a.call(arguments,0):[],up.migrate.warn("up.util.detect() has been renamed to up.util.find()"),(t=up.util).find.apply(t,e)},up.util.select=function(){var e,t;return e=1<=arguments.length?a.call(arguments,0):[],up.migrate.warn("up.util.select() has been renamed to up.util.filter()"),(t=up.util).filter.apply(t,e)},up.util.setTimer=function(){var e,t;return e=1<=arguments.length?a.call(arguments,0):[],up.migrate.warn("up.util.setTimer() has been renamed to up.util.timer()"),(t=up.util).timer.apply(t,e)},up.util.escapeHtml=function(){var e,t;return e=1<=arguments.length?a.call(arguments,0):[],up.migrate.deprecated("up.util.escapeHtml","up.util.escapeHTML"),(t=up.util).escapeHTML.apply(t,e)},up.util.selectorForElement=function(){var e,t;return e=1<=arguments.length?a.call(arguments,0):[],up.migrate.warn("up.util.selectorForElement() has been renamed to up.fragment.toTarget()"),(t=up.fragment).toTarget.apply(t,e)},up.util.nextFrame=function(){var e,t;return e=1<=arguments.length?a.call(arguments,0):[],up.migrate.warn("up.util.nextFrame() has been renamed to up.util.task()"),(t=up.util).task.apply(t,e)}}.call(this),function(){var r=[].slice;up.element.first=function(){var e,t;return e=1<=arguments.length?r.call(arguments,0):[],up.migrate.deprecated("up.element.first()","up.element.get()"),(t=up.element).get.apply(t,e)},up.element.createFromHtml=function(){var e,t;return e=1<=arguments.length?r.call(arguments,0):[],up.migrate.deprecated("up.element.createFromHtml","up.element.createFromHTML"),(t=up.element).createFromHTML.apply(t,e)}}.call(this),function(){var t=[].slice;up.migrate.renamedPackage("bus","event"),up.event.nobodyPrevents=function(){var e;return e=1<=arguments.length?t.call(arguments,0):[],up.migrate.deprecated("up.event.nobodyPrevents(type)","!up.emit(type).defaultPrevented"),!up.emit.apply(up,e).defaultPrevented}}.call(this),function(){up.migrate.renamedProperty(up.form.config,"fields","fieldSelectors"),up.migrate.renamedProperty(up.form.config,"submitButtons","submitButtonSelectors")}.call(this),function(){var p,r=[].slice;p=up.util,up.migrate.renamedPackage("flow","fragment"),up.migrate.renamedPackage("dom","fragment"),up.migrate.renamedProperty(up.fragment.config,"fallbacks","mainTargets"),up.migrate.handleResponseDocOptions=function(e){return up.migrate.fixKey(e,"html","document")},up.replace=function(e,t,r){return up.migrate.deprecated("up.replace(target, url)","up.navigate(target, { url })"),up.navigate(p.merge(r,{target:e,url:t}))},up.extract=function(e,t,r){return up.migrate.deprecated("up.extract(target, document)","up.navigate(target, { document })"),up.navigate(p.merge(r,{target:e,document:t}))},up.fragment.first=function(){var e,t;return e=1<=arguments.length?r.call(arguments,0):[],up.migrate.deprecated("up.fragment.first()","up.fragment.get()"),(t=up.fragment).get.apply(t,e)},up.first=up.fragment.first,up.migrate.handleScrollOptions=function(e){if(p.isUndefined(e.scroll)&&(p.isString(e.reveal)?(up.migrate.deprecated("Option { reveal: '"+e.reveal+"' }","{ scroll: '"+e.reveal+"' }"),e.scroll=e.reveal):!0===e.reveal?(up.migrate.deprecated("Option { reveal: true }","{ scroll: 'target' }"),e.scroll="target"):!1===e.reveal&&(up.migrate.deprecated("Option { reveal: false }","{ scroll: false }"),e.scroll=!1),p.isDefined(e.resetScroll)&&(up.migrate.deprecated("Option { resetScroll: true }","{ scroll: 'reset' }"),e.scroll="teset"),p.isDefined(e.restoreScroll)))return up.migrate.deprecated("Option { restoreScroll: true }","{ scroll: 'restore' }"),e.scroll="restore"},up.migrate.handleHistoryOption=function(e){if(p.isString(e.history)&&"auto"!==e.history)return up.migrate.warn("Passing a URL as { history } option is deprecated. Pass it as { location } instead."),e.location=e.history,e.history="auto"},up.migrate.handleRenderOptions=function(e){var t,r,a,n,u;for(up.migrate.handleHistoryOption(e),u=[],t=0,r=(n=["target","origin"]).length;t<r;t++)a=n[t],p.isJQuery(e[a])?(up.migrate.warn("Passing a jQuery collection as { %s } is deprecated. Pass it as a native element instead.",a),u.push(e[a]=up.element.get(e[a]))):u.push(void 0);return u}}.call(this),function(){up.migrate.renamedProperty(up.history.config,"popTargets","restoreTargets"),up.history.url=function(){return up.migrate.deprecated("up.history.url()","up.history.location"),up.history.location},up.migrate.renamedEvent("up:history:push","up:location:changed"),up.migrate.renamedEvent("up:history:pushed","up:location:changed"),up.migrate.renamedEvent("up:history:restore","up:location:changed"),up.migrate.renamedEvent("up:history:restored","up:location:changed"),up.migrate.renamedEvent("up:history:replaced","up:location:changed")}.call(this),function(){up.migrate.renamedPackage("navigation","feedback"),up.migrate.renamedProperty(up.feedback.config,"navs","navSelectors")}.call(this),function(){up.migrate.parseFollowOptions=function(e){return e.string("flavor"),e.string("width"),e.string("height"),e["boolean"]("closable"),e.booleanOrString("reveal"),e["boolean"]("resetScroll"),e["boolean"]("restoreScroll")}}.call(this),function(){up.migrate.handleLayerOptions=function(e){var t,r,a,n;for(up.migrate.fixKey(e,"flavor","mode"),up.migrate.fixKey(e,"closable","dismissable"),up.migrate.fixKey(e,"closeLabel","dismissLabel"),r=0,a=(n=["width","maxWidth","height"]).length;r<a;r++)e[t=n[r]]&&up.migrate.warn("Layer option { "+t+" } has been removed. Use { size } or { class } instead.");if(e.sticky&&up.migrate.warn("Layer option { sticky } has been removed. Give links an [up-peel=false] attribute to prevent layer dismissal on click."),e.template&&up.migrate.warn("Layer option { template } has been removed. Use { class } or modify the layer HTML on up:layer:open."),"page"===e.layer&&(up.migrate.warn("Option { layer: 'page' } has been renamed to { layer: 'root' }."),e.layer="root"),"modal"===e.layer||"popup"===e.layer)return up.migrate.warn("Option { layer: '"+e.layer+"' } has been removed. Did you mean { layer: 'overlay' }?"),e.layer="overlay"},up.migrate.handleTetherOptions=function(e){var t,r,a;if(r=(a=e.position.split("-"))[0],t=a[1])return up.migrate.warn("The position value %o is deprecated. Use %o instead.",e.position,{position:r,align:t}),e.position=r,e.align=t},up.migrate.registerLayerCloser=function(r){return r.registerClickCloser("up-close",function(e,t){return up.migrate.deprecated("[up-close]","[up-dismiss]"),r.dismiss(e,t)})},up.migrate.handleLayerConfig=function(e){return up.migrate.fixKey(e,"history","historyVisible")}}.call(this),function(){var e,a;a=up.util,e=new Error("up.modal.flavors has been removed without direct replacement. You may give new layers a { class } or modify layer elements on up:layer:open."),up.modal=a.literal({visit:function(e,t){return null==t&&(t={}),up.migrate.deprecated("up.modal.visit(url)",'up.layer.open({ url, mode: "modal" })'),up.layer.open(a.merge(t,{url:e,mode:"modal"}))},follow:function(e,t){return null==t&&(t={}),up.migrate.deprecated("up.modal.follow(link)",'up.follow(link, { layer: "modal" })'),up.follow(e,a.merge(t,{layer:"modal"}))},extract:function(e,t,r){return null==r&&(r={}),up.migrate.deprecated("up.modal.extract(target, document)",'up.layer.open({ document, mode: "modal" })'),up.layer.open(a.merge(r,{target:e,html:t,layer:"modal"}))},close:function(e){return null==e&&(e={}),up.migrate.deprecated("up.modal.close()","up.layer.dismiss()"),up.layer.dismiss(null,e),up.migrate.formerlyAsync("up.layer.dismiss()")},url:function(){return up.migrate.deprecated("up.modal.url()","up.layer.location"),up.layer.location},coveredUrl:function(){var e;return up.migrate.deprecated("up.modal.coveredUrl()","up.layer.parent.location"),null!=(e=up.layer.parent)?e.location:void 0},get_config:function(){return up.migrate.deprecated("up.modal.config","up.layer.config.modal"),up.layer.config.modal},contains:function(e){return up.migrate.deprecated("up.modal.contains()","up.layer.contains()"),up.layer.contains(e)},isOpen:function(){return up.migrate.deprecated("up.modal.isOpen()","up.layer.isOverlay()"),up.layer.isOverlay()},get_flavors:function(){throw e},flavor:function(){throw e}}),up.migrate.renamedEvent("up:modal:open","up:layer:open"),up.migrate.renamedEvent("up:modal:opened","up:layer:opened"),up.migrate.renamedEvent("up:modal:close","up:layer:dismiss"),up.migrate.renamedEvent("up:modal:closed","up:layer:dismissed"),up.link.targetMacro("up-modal",{"up-layer":"new modal"},function(){return up.migrate.deprecated("a[up-modal]",'a[up-layer="new modal"]')}),up.link.targetMacro("up-drawer",{"up-layer":"new drawer"},function(){return up.migrate.deprecated("a[up-drawer]",'a[up-layer="new drawer"]')})}.call(this),function(){var r;r=up.util,up.element,up.popup=r.literal({attach:function(e,t){return null==t&&(t={}),e=up.fragment.get(e),up.migrate.deprecated("up.popup.attach(origin)","up.layer.open({ origin, layer: 'popup' })"),up.layer.open(r.merge(t,{origin:e,layer:"popup"}))},close:function(e){return null==e&&(e={}),up.migrate.deprecated("up.popup.close()","up.layer.dismiss()"),up.layer.dismiss(null,e)},url:function(){return up.migrate.deprecated("up.popup.url()","up.layer.location"),up.layer.location},coveredUrl:function(){var e;return up.migrate.deprecated("up.popup.coveredUrl()","up.layer.parent.location"),null!=(e=up.layer.parent)?e.location:void 0},get_config:function(){return up.migrate.deprecated("up.popup.config","up.layer.config.popup"),up.layer.config.popup},contains:function(e){return up.migrate.deprecated("up.popup.contains()","up.layer.contains()"),up.layer.contains(e)},isOpen:function(){return up.migrate.deprecated("up.popup.isOpen()","up.layer.isOverlay()"),up.layer.isOverlay()},sync:function(){return up.migrate.deprecated("up.popup.sync()","up.layer.sync()"),up.layer.sync()}}),up.migrate.renamedEvent("up:popup:open","up:layer:open"),up.migrate.renamedEvent("up:popup:opened","up:layer:opened"),up.migrate.renamedEvent("up:popup:close","up:layer:dismiss"),up.migrate.renamedEvent("up:popup:closed","up:layer:dismissed"),up.link.targetMacro("up-popup",{"up-layer":"new popup"},function(){return up.migrate.deprecated("[up-popup]",'[up-layer="new popup"]')})}.call(this),function(){up.tooltip=up.macro("[up-tooltip]",function(e){return up.migrate.warn("[up-tooltip] has been deprecated. A [title] was set instead."),up.element.setMissingAttr(e,"title",e.getAttribute("up-tooltip"))})}.call(this),function(){var t,r,a=[].slice;r=up.util,up.migrate.renamedPackage("proxy","network"),up.migrate.renamedEvent("up:proxy:load","up:request:load"),up.migrate.renamedEvent("up:proxy:received","up:request:loaded"),up.migrate.renamedEvent("up:proxy:loaded","up:request:loaded"),up.migrate.renamedEvent("up:proxy:fatal","up:request:fatal"),up.migrate.renamedEvent("up:proxy:aborted","up:request:aborted"),up.migrate.renamedEvent("up:proxy:slow","up:request:late"),up.migrate.renamedEvent("up:proxy:recover","up:request:recover"),t=function(){return up.migrate.deprecated("up.proxy.config.preloadDelay","up.link.config.preloadDelay")},Object.defineProperty(up.network.config,"preloadDelay",{get:function(){return t(),up.link.config.preloadDelay},set:function(e){return t(),up.link.config.preloadDelay=e}}),up.migrate.renamedProperty(up.network.config,"maxRequests","concurrency"),up.migrate.renamedProperty(up.network.config,"slowDelay","badResponseTime"),up.migrate.handleNetworkPreloadArgs=function(){var e,t;if(e=1<=arguments.length?a.call(arguments,0):[],r.isElementish(e[0]))return up.migrate.warn("up.proxy.preload(link) has been renamed to up.link.preload(link)"),(t=up.link).preload.apply(t,e)},up.migrate.handleRequestOptions=function(e){return up.migrate.fixKey(e,"data","params")},up.ajax=function(){var e,t;return e=1<=arguments.length?a.call(arguments,0):[],up.migrate.deprecated("up.ajax()","up.request()"),t=function(e){return e.text},up.request.apply(up,e).then(t)},up.network.clear=function(){return up.migrate.deprecated("up.proxy.clear()","up.cache.clear()"),up.cache.clear()},up.Request.prototype.navigate=function(){return up.migrate.deprecated("up.Request#navigate()","up.Request#loadPage()"),this.loadPage()},up.Response.prototype.isSuccess=function(){return up.migrate.deprecated("up.Response#isSuccess()","up.Response#ok"),this.ok},up.Response.prototype.isError=function(){return up.migrate.deprecated("up.Response#isError()","!up.Response#ok"),!this.ok}}.call(this),function(){up.migrate.renamedProperty(up.radio.config,"hungry","hungrySelectors")}.call(this),function(){var r=[].slice;up.migrate.renamedPackage("layout","viewport"),up.migrate.renamedProperty(up.viewport.config,"viewports","viewportSelectors"),up.migrate.renamedProperty(up.viewport.config,"snap","revealSnap"),up.viewport.closest=function(){var e,t;return e=1<=arguments.length?r.call(arguments,0):[],up.migrate.deprecated("up.viewport.closest()","up.viewport.get()"),(t=up.viewport).get.apply(t,e)}}.call(this),function(){up.framework.stopExtension()}.call(this),function(){}.call(this);
1
+ (function(){up.framework.startExtension()}).call(this),function(){var u,p,e,t,r,a,n,i,o,l,c,s,m,d,g=[].slice;u=up.util,up.migrate=(p=new up.Config(function(){return{logLevel:"warn"}}),c=function(e,t,r){var a;return a=function(){return m("Property { %s } has been renamed to { %s } (found in %o)",t,r,e)},Object.defineProperty(e,t,{get:function(){return a(),this[r]},set:function(e){return a(),this[r]=e}})},a=function(e,t,r){if(u.isDefined(e[t]))return m("Property { %s } has been renamed to { %s } (found in %o)",t,r,e),u.renameKey(e,t,r)},o={},i=function(e,t){return o[e]=t},t=function(e){var t;return(t=o[e])?(m("Event "+e+" has been renamed to "+t),t):e},r=function(e){return u.uniq(u.map(e,t))},l=function(e,t){return Object.defineProperty(up,e,{get:function(){return m("up."+e+" has been renamed to up."+t),up[t]}})},d={},m=function(e){var t,r,a,n;if(a=e,t=2<=arguments.length?g.call(arguments,1):[],r=u.sprintf.apply(u,[a].concat(g.call(t))),!d[r])return d[r]=!0,(n=up.log)[p.logLevel].apply(n,["DEPRECATION",a].concat(g.call(t)))},e=function(e,t){return m(e+" has been deprecated. Use "+t+" instead.")},n=function(e){var t,r;return r=Promise.resolve(),t=r.then,r.then=function(){return m(e+" is now a sync function"),t.apply(this,arguments)},r},s=function(){return p.reset()},up.on("up:framework:reset",s),{deprecated:e,renamedPackage:l,renamedProperty:c,formerlyAsync:n,renamedEvent:i,fixEventTypes:r,fixKey:a,warn:m,loaded:!0,config:p})}.call(this),function(){var a=[].slice;up.util.only=function(e){var t,r;return r=e,t=2<=arguments.length?a.call(arguments,1):[],up.migrate.deprecated("up.util.only(object, ...keys)","up.util.pick(object, keys)"),up.util.pick(r,t)},up.util.except=function(e){var t,r;return r=e,t=2<=arguments.length?a.call(arguments,1):[],up.migrate.deprecated("up.util.except(object, ...keys)","up.util.omit(object, keys)"),up.util.omit(r,t)},up.util.parseUrl=function(){var e,t;return e=1<=arguments.length?a.call(arguments,0):[],up.migrate.warn("up.util.parseUrl() has been renamed to up.util.parseURL()"),(t=up.util).parseURL.apply(t,e)},up.util.any=function(){var e;return e=1<=arguments.length?a.call(arguments,0):[],up.migrate.warn("up.util.any() has been renamed to up.util.some()"),some.apply(null,e)},up.util.all=function(){var e,t;return e=1<=arguments.length?a.call(arguments,0):[],up.migrate.warn("up.util.all() has been renamed to up.util.every()"),(t=up.util).every.apply(t,e)},up.util.detect=function(){var e,t;return e=1<=arguments.length?a.call(arguments,0):[],up.migrate.warn("up.util.detect() has been renamed to up.util.find()"),(t=up.util).find.apply(t,e)},up.util.select=function(){var e,t;return e=1<=arguments.length?a.call(arguments,0):[],up.migrate.warn("up.util.select() has been renamed to up.util.filter()"),(t=up.util).filter.apply(t,e)},up.util.setTimer=function(){var e,t;return e=1<=arguments.length?a.call(arguments,0):[],up.migrate.warn("up.util.setTimer() has been renamed to up.util.timer()"),(t=up.util).timer.apply(t,e)},up.util.escapeHtml=function(){var e,t;return e=1<=arguments.length?a.call(arguments,0):[],up.migrate.deprecated("up.util.escapeHtml","up.util.escapeHTML"),(t=up.util).escapeHTML.apply(t,e)},up.util.selectorForElement=function(){var e,t;return e=1<=arguments.length?a.call(arguments,0):[],up.migrate.warn("up.util.selectorForElement() has been renamed to up.fragment.toTarget()"),(t=up.fragment).toTarget.apply(t,e)},up.util.nextFrame=function(){var e,t;return e=1<=arguments.length?a.call(arguments,0):[],up.migrate.warn("up.util.nextFrame() has been renamed to up.util.task()"),(t=up.util).task.apply(t,e)}}.call(this),function(){var r=[].slice;up.element.first=function(){var e,t;return e=1<=arguments.length?r.call(arguments,0):[],up.migrate.deprecated("up.element.first()","up.element.get()"),(t=up.element).get.apply(t,e)},up.element.createFromHtml=function(){var e,t;return e=1<=arguments.length?r.call(arguments,0):[],up.migrate.deprecated("up.element.createFromHtml","up.element.createFromHTML"),(t=up.element).createFromHTML.apply(t,e)}}.call(this),function(){var t=[].slice;up.migrate.renamedPackage("bus","event"),up.event.nobodyPrevents=function(){var e;return e=1<=arguments.length?t.call(arguments,0):[],up.migrate.deprecated("up.event.nobodyPrevents(type)","!up.emit(type).defaultPrevented"),!up.emit.apply(up,e).defaultPrevented}}.call(this),function(){up.migrate.renamedProperty(up.form.config,"fields","fieldSelectors"),up.migrate.renamedProperty(up.form.config,"submitButtons","submitButtonSelectors")}.call(this),function(){var p,r=[].slice;p=up.util,up.migrate.renamedPackage("flow","fragment"),up.migrate.renamedPackage("dom","fragment"),up.migrate.renamedProperty(up.fragment.config,"fallbacks","mainTargets"),up.migrate.handleResponseDocOptions=function(e){return up.migrate.fixKey(e,"html","document")},up.replace=function(e,t,r){return up.migrate.deprecated("up.replace(target, url)","up.navigate(target, { url })"),up.navigate(p.merge(r,{target:e,url:t}))},up.extract=function(e,t,r){return up.migrate.deprecated("up.extract(target, document)","up.navigate(target, { document })"),up.navigate(p.merge(r,{target:e,document:t}))},up.fragment.first=function(){var e,t;return e=1<=arguments.length?r.call(arguments,0):[],up.migrate.deprecated("up.fragment.first()","up.fragment.get()"),(t=up.fragment).get.apply(t,e)},up.first=up.fragment.first,up.migrate.handleScrollOptions=function(e){if(p.isUndefined(e.scroll)&&(p.isString(e.reveal)?(up.migrate.deprecated("Option { reveal: '"+e.reveal+"' }","{ scroll: '"+e.reveal+"' }"),e.scroll=e.reveal):!0===e.reveal?(up.migrate.deprecated("Option { reveal: true }","{ scroll: 'target' }"),e.scroll="target"):!1===e.reveal&&(up.migrate.deprecated("Option { reveal: false }","{ scroll: false }"),e.scroll=!1),p.isDefined(e.resetScroll)&&(up.migrate.deprecated("Option { resetScroll: true }","{ scroll: 'reset' }"),e.scroll="teset"),p.isDefined(e.restoreScroll)))return up.migrate.deprecated("Option { restoreScroll: true }","{ scroll: 'restore' }"),e.scroll="restore"},up.migrate.handleHistoryOption=function(e){if(p.isString(e.history)&&"auto"!==e.history)return up.migrate.warn("Passing a URL as { history } option is deprecated. Pass it as { location } instead."),e.location=e.history,e.history="auto"},up.migrate.handleRenderOptions=function(e){var t,r,a,n,u;for(up.migrate.handleHistoryOption(e),u=[],t=0,r=(n=["target","origin"]).length;t<r;t++)a=n[t],p.isJQuery(e[a])?(up.migrate.warn("Passing a jQuery collection as { %s } is deprecated. Pass it as a native element instead.",a),u.push(e[a]=up.element.get(e[a]))):u.push(void 0);return u}}.call(this),function(){up.migrate.renamedProperty(up.history.config,"popTargets","restoreTargets"),up.history.url=function(){return up.migrate.deprecated("up.history.url()","up.history.location"),up.history.location},up.migrate.renamedEvent("up:history:push","up:location:changed"),up.migrate.renamedEvent("up:history:pushed","up:location:changed"),up.migrate.renamedEvent("up:history:restore","up:location:changed"),up.migrate.renamedEvent("up:history:restored","up:location:changed"),up.migrate.renamedEvent("up:history:replaced","up:location:changed")}.call(this),function(){up.migrate.renamedPackage("navigation","feedback"),up.migrate.renamedProperty(up.feedback.config,"navs","navSelectors")}.call(this),function(){up.migrate.parseFollowOptions=function(e){return e.string("flavor"),e.string("width"),e.string("height"),e["boolean"]("closable"),e.booleanOrString("reveal"),e["boolean"]("resetScroll"),e["boolean"]("restoreScroll")}}.call(this),function(){up.migrate.handleLayerOptions=function(e){var t,r,a,n;for(up.migrate.fixKey(e,"flavor","mode"),up.migrate.fixKey(e,"closable","dismissable"),up.migrate.fixKey(e,"closeLabel","dismissLabel"),r=0,a=(n=["width","maxWidth","height"]).length;r<a;r++)e[t=n[r]]&&up.migrate.warn("Layer option { "+t+" } has been removed. Use { size } or { class } instead.");if(e.sticky&&up.migrate.warn("Layer option { sticky } has been removed. Give links an [up-peel=false] attribute to prevent layer dismissal on click."),e.template&&up.migrate.warn("Layer option { template } has been removed. Use { class } or modify the layer HTML on up:layer:open."),"page"===e.layer&&(up.migrate.warn("Option { layer: 'page' } has been renamed to { layer: 'root' }."),e.layer="root"),"modal"===e.layer||"popup"===e.layer)return up.migrate.warn("Option { layer: '"+e.layer+"' } has been removed. Did you mean { layer: 'overlay' }?"),e.layer="overlay"},up.migrate.handleTetherOptions=function(e){var t,r,a;if(r=(a=e.position.split("-"))[0],t=a[1])return up.migrate.warn("The position value %o is deprecated. Use %o instead.",e.position,{position:r,align:t}),e.position=r,e.align=t},up.migrate.registerLayerCloser=function(r){return r.registerClickCloser("up-close",function(e,t){return up.migrate.deprecated("[up-close]","[up-dismiss]"),r.dismiss(e,t)})},up.migrate.handleLayerConfig=function(e){return up.migrate.fixKey(e,"history","historyVisible")}}.call(this),function(){var e,a;a=up.util,e=new Error("up.modal.flavors has been removed without direct replacement. You may give new layers a { class } or modify layer elements on up:layer:open."),up.modal=a.literal({visit:function(e,t){return null==t&&(t={}),up.migrate.deprecated("up.modal.visit(url)",'up.layer.open({ url, mode: "modal" })'),up.layer.open(a.merge(t,{url:e,mode:"modal"}))},follow:function(e,t){return null==t&&(t={}),up.migrate.deprecated("up.modal.follow(link)",'up.follow(link, { layer: "modal" })'),up.follow(e,a.merge(t,{layer:"modal"}))},extract:function(e,t,r){return null==r&&(r={}),up.migrate.deprecated("up.modal.extract(target, document)",'up.layer.open({ document, mode: "modal" })'),up.layer.open(a.merge(r,{target:e,html:t,layer:"modal"}))},close:function(e){return null==e&&(e={}),up.migrate.deprecated("up.modal.close()","up.layer.dismiss()"),up.layer.dismiss(null,e),up.migrate.formerlyAsync("up.layer.dismiss()")},url:function(){return up.migrate.deprecated("up.modal.url()","up.layer.location"),up.layer.location},coveredUrl:function(){var e;return up.migrate.deprecated("up.modal.coveredUrl()","up.layer.parent.location"),null!=(e=up.layer.parent)?e.location:void 0},get_config:function(){return up.migrate.deprecated("up.modal.config","up.layer.config.modal"),up.layer.config.modal},contains:function(e){return up.migrate.deprecated("up.modal.contains()","up.layer.contains()"),up.layer.contains(e)},isOpen:function(){return up.migrate.deprecated("up.modal.isOpen()","up.layer.isOverlay()"),up.layer.isOverlay()},get_flavors:function(){throw e},flavor:function(){throw e}}),up.migrate.renamedEvent("up:modal:open","up:layer:open"),up.migrate.renamedEvent("up:modal:opened","up:layer:opened"),up.migrate.renamedEvent("up:modal:close","up:layer:dismiss"),up.migrate.renamedEvent("up:modal:closed","up:layer:dismissed"),up.link.targetMacro("up-modal",{"up-layer":"new modal"},function(){return up.migrate.deprecated("a[up-modal]",'a[up-layer="new modal"]')}),up.link.targetMacro("up-drawer",{"up-layer":"new drawer"},function(){return up.migrate.deprecated("a[up-drawer]",'a[up-layer="new drawer"]')})}.call(this),function(){var r;r=up.util,up.element,up.popup=r.literal({attach:function(e,t){return null==t&&(t={}),e=up.fragment.get(e),up.migrate.deprecated("up.popup.attach(origin)","up.layer.open({ origin, layer: 'popup' })"),up.layer.open(r.merge(t,{origin:e,layer:"popup"}))},close:function(e){return null==e&&(e={}),up.migrate.deprecated("up.popup.close()","up.layer.dismiss()"),up.layer.dismiss(null,e)},url:function(){return up.migrate.deprecated("up.popup.url()","up.layer.location"),up.layer.location},coveredUrl:function(){var e;return up.migrate.deprecated("up.popup.coveredUrl()","up.layer.parent.location"),null!=(e=up.layer.parent)?e.location:void 0},get_config:function(){return up.migrate.deprecated("up.popup.config","up.layer.config.popup"),up.layer.config.popup},contains:function(e){return up.migrate.deprecated("up.popup.contains()","up.layer.contains()"),up.layer.contains(e)},isOpen:function(){return up.migrate.deprecated("up.popup.isOpen()","up.layer.isOverlay()"),up.layer.isOverlay()},sync:function(){return up.migrate.deprecated("up.popup.sync()","up.layer.sync()"),up.layer.sync()}}),up.migrate.renamedEvent("up:popup:open","up:layer:open"),up.migrate.renamedEvent("up:popup:opened","up:layer:opened"),up.migrate.renamedEvent("up:popup:close","up:layer:dismiss"),up.migrate.renamedEvent("up:popup:closed","up:layer:dismissed"),up.link.targetMacro("up-popup",{"up-layer":"new popup"},function(){return up.migrate.deprecated("[up-popup]",'[up-layer="new popup"]')})}.call(this),function(){up.tooltip=up.macro("[up-tooltip]",function(e){return up.migrate.warn("[up-tooltip] has been deprecated. A [title] was set instead."),up.element.setMissingAttr(e,"title",e.getAttribute("up-tooltip"))})}.call(this),function(){var t,r,a=[].slice;r=up.util,up.migrate.renamedPackage("proxy","network"),up.migrate.renamedEvent("up:proxy:load","up:request:load"),up.migrate.renamedEvent("up:proxy:received","up:request:loaded"),up.migrate.renamedEvent("up:proxy:loaded","up:request:loaded"),up.migrate.renamedEvent("up:proxy:fatal","up:request:fatal"),up.migrate.renamedEvent("up:proxy:aborted","up:request:aborted"),up.migrate.renamedEvent("up:proxy:slow","up:request:late"),up.migrate.renamedEvent("up:proxy:recover","up:request:recover"),t=function(){return up.migrate.deprecated("up.proxy.config.preloadDelay","up.link.config.preloadDelay")},Object.defineProperty(up.network.config,"preloadDelay",{get:function(){return t(),up.link.config.preloadDelay},set:function(e){return t(),up.link.config.preloadDelay=e}}),up.migrate.renamedProperty(up.network.config,"maxRequests","concurrency"),up.migrate.renamedProperty(up.network.config,"slowDelay","badResponseTime"),up.migrate.handleNetworkPreloadArgs=function(){var e,t;if(e=1<=arguments.length?a.call(arguments,0):[],r.isElementish(e[0]))return up.migrate.warn("up.proxy.preload(link) has been renamed to up.link.preload(link)"),(t=up.link).preload.apply(t,e)},up.migrate.handleRequestOptions=function(e){return up.migrate.fixKey(e,"data","params")},up.ajax=function(){var e,t;return e=1<=arguments.length?a.call(arguments,0):[],up.migrate.deprecated("up.ajax()","up.request()"),t=function(e){return e.text},up.request.apply(up,e).then(t)},up.network.clear=function(){return up.migrate.deprecated("up.proxy.clear()","up.cache.clear()"),up.cache.clear()},up.Request.prototype.navigate=function(){return up.migrate.deprecated("up.Request#navigate()","up.Request#loadPage()"),this.loadPage()},up.Response.prototype.isSuccess=function(){return up.migrate.deprecated("up.Response#isSuccess()","up.Response#ok"),this.ok},up.Response.prototype.isError=function(){return up.migrate.deprecated("up.Response#isError()","!up.Response#ok"),!this.ok}}.call(this),function(){up.migrate.renamedProperty(up.radio.config,"hungry","hungrySelectors")}.call(this),function(){var o;o=up.util,up.migrate.postCompile=function(e,t){var r,a,n,u,p,i;if(n=t.keep){for(up.migrate.warn("The { keep: true } option for up.compiler() has been removed. Have the compiler set [up-keep] attribute instead."),i=o.isString(n)?n:"",p=[],a=0,u=e.length;a<u;a++)r=e[a],p.push(r.setAttribute("up-keep",i));return p}}}.call(this),function(){var r=[].slice;up.migrate.renamedPackage("layout","viewport"),up.migrate.renamedProperty(up.viewport.config,"viewports","viewportSelectors"),up.migrate.renamedProperty(up.viewport.config,"snap","revealSnap"),up.viewport.closest=function(){var e,t;return e=1<=arguments.length?r.call(arguments,0):[],up.migrate.deprecated("up.viewport.closest()","up.viewport.get()"),(t=up.viewport).get.apply(t,e)}}.call(this),function(){up.framework.stopExtension()}.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: "2.0.0-rc10"
8
+ version: "2.0.0-rc11"
9
9
  };
10
10
 
11
11
  }).call(this);
@@ -110,20 +110,21 @@ to not include another library in your asset bundle.
110
110
  };
111
111
 
112
112
  /***
113
- Normalizes relative paths and absolute paths to a full URL
114
- that can be checked for equality with other normalized URLs.
115
-
116
- By default hashes are ignored, search queries are included.
113
+ Normalizes the given URL or path.
117
114
 
118
115
  @function up.util.normalizeURL
119
116
  @param {boolean} [options.host='cross-domain']
120
117
  Whether to include protocol, hostname and port in the normalized URL.
118
+
119
+ By default the host is only included if it differ's from the page's hostname.
121
120
  @param {boolean} [options.hash=false]
122
121
  Whether to include an `#hash` anchor in the normalized URL
123
122
  @param {boolean} [options.search=true]
124
123
  Whether to include a `?query` string in the normalized URL
125
124
  @param {boolean} [options.stripTrailingSlash=false]
126
125
  Whether to strip a trailing slash from the pathname
126
+ @return {string}
127
+ The normalized URL.
127
128
  @internal
128
129
  */
129
130
  normalizeURL = function(urlOrAnchor, options) {
@@ -178,6 +179,15 @@ to not include another library in your asset bundle.
178
179
  If the given URL is not fully qualified, it is assumed to be relative
179
180
  to the current page.
180
181
 
182
+ \#\#\# Example
183
+
184
+ ```js
185
+ let parsed = up.util.parseURL('/path?foo=value')
186
+ parsed.pathname // => '/path'
187
+ parsed.search // => '/?foo=value'
188
+ parsed.hash // => ''
189
+ ```
190
+
181
191
  @function up.util.parseURL
182
192
  @return {Object}
183
193
  The parsed URL as an object with
@@ -732,7 +742,7 @@ to not include another library in your asset bundle.
732
742
  @function up.util.isList
733
743
  @param value
734
744
  @return {boolean}
735
- @experimental
745
+ @stable
736
746
  */
737
747
  isList = function(value) {
738
748
  return isArray(value) || isNodeList(value) || isArguments(value) || isJQuery(value) || isHTMLCollection(value);
@@ -775,9 +785,20 @@ to not include another library in your asset bundle.
775
785
  };
776
786
 
777
787
  /***
788
+ Returns the given value if it is [array-like](/up.util.isList), otherwise
789
+ returns an array with the given value as its only element.
790
+
791
+ \#\#\# Example
792
+
793
+ ```js
794
+ up.util.wrapList([1, 2, 3]) // => [1, 2, 3]
795
+ up.util.wrapList('foo') // => ['foo']
796
+ ```
797
+
778
798
  @function up.util.wrapList
799
+ @param {any} value
779
800
  @return {Array|NodeList|jQuery}
780
- @internal
801
+ @experimental
781
802
  */
782
803
  wrapList = function(value) {
783
804
  if (isList(value)) {
@@ -1281,6 +1302,7 @@ to not include another library in your asset bundle.
1281
1302
  @function up.util.pick
1282
1303
  @param {Object} object
1283
1304
  @param {Array} keys
1305
+ @return {Object}
1284
1306
  @stable
1285
1307
  */
1286
1308
  pick = function(object, keys) {
@@ -1294,6 +1316,20 @@ to not include another library in your asset bundle.
1294
1316
  }
1295
1317
  return filtered;
1296
1318
  };
1319
+
1320
+ /***
1321
+ Returns a copy of the given object that only contains
1322
+ properties that pass the given tester function.
1323
+
1324
+ @function up.util.pickBy
1325
+ @param {Object} object
1326
+ @param {Function<string, string, object>} tester
1327
+ A function that will be called with each property.
1328
+
1329
+ The arguments are the property value, key and the entire object.
1330
+ @return {Object}
1331
+ @experimental
1332
+ */
1297
1333
  pickBy = function(object, tester) {
1298
1334
  var filtered, key, value;
1299
1335
  tester = iteratee(tester);
@@ -1359,8 +1395,20 @@ to not include another library in your asset bundle.
1359
1395
  If the given `value` is a function, calls the function with the given `args`.
1360
1396
  Otherwise it just returns `value`.
1361
1397
 
1398
+ \#\#\# Example
1399
+
1400
+ ```js
1401
+ up.util.evalOption(5) // => 5
1402
+
1403
+ let fn = () => 1 + 2
1404
+ up.util.evalOption(fn) // => 3
1405
+ ```
1406
+
1362
1407
  @function up.util.evalOption
1363
- @internal
1408
+ @param {any} value
1409
+ @param {Array} ...args
1410
+ @return {any}
1411
+ @experimental
1364
1412
  */
1365
1413
  evalOption = function() {
1366
1414
  var args, value;
@@ -1384,7 +1432,7 @@ to not include another library in your asset bundle.
1384
1432
 
1385
1433
  @function up.util.escapeHTML
1386
1434
  @param {string} string
1387
- The text that should be escaped
1435
+ The text that should be escaped.
1388
1436
  @stable
1389
1437
  */
1390
1438
  escapeHTML = function(string) {
@@ -1400,6 +1448,17 @@ to not include another library in your asset bundle.
1400
1448
  escapeRegExp = function(string) {
1401
1449
  return string.replace(/[\\^$*+?.()|[\]{}]/g, '\\$&');
1402
1450
  };
1451
+
1452
+ /***
1453
+ Deletes the property with the given key from the given object
1454
+ and returns its value.
1455
+
1456
+ @function up.util.pluckKey
1457
+ @param {Object} object
1458
+ @param {string} key
1459
+ @return {any}
1460
+ @experimental
1461
+ */
1403
1462
  pluckKey = function(object, key) {
1404
1463
  var value;
1405
1464
  value = object[key];
@@ -1431,7 +1490,6 @@ to not include another library in your asset bundle.
1431
1490
  @param {Array<Function()>} functions
1432
1491
  @return {Function()}
1433
1492
  A function that will call all `functions` if called.
1434
-
1435
1493
  @internal
1436
1494
  */
1437
1495
  sequence = function(functions) {
@@ -1447,7 +1505,13 @@ to not include another library in your asset bundle.
1447
1505
  };
1448
1506
 
1449
1507
  /***
1450
- Flattens the given `array` a single level deep.
1508
+ Flattens the given `array` a single depth level.
1509
+
1510
+ \#\#\# Example
1511
+
1512
+ ```js
1513
+ let nested = [1, [2, 3], [4]]
1514
+ up.util.flatten(nested) // => [1, 2, 3, 4]
1451
1515
 
1452
1516
  @function up.util.flatten
1453
1517
  @param {Array} array
@@ -1472,7 +1536,7 @@ to not include another library in your asset bundle.
1472
1536
 
1473
1537
  /***
1474
1538
  Maps each element using a mapping function,
1475
- then flattens the result into a new array.
1539
+ then [flattens](/up.util.flatten) the result into a new array.
1476
1540
 
1477
1541
  @function up.util.flatMap
1478
1542
  @param {Array} array
@@ -2559,7 +2623,7 @@ It complements [native `Element` methods](https://www.w3schools.com/jsref/dom_ob
2559
2623
  @function up.element.toggleClass
2560
2624
  @param {Element} element
2561
2625
  The element for which to add or remove the class.
2562
- @param {String} className
2626
+ @param {string} className
2563
2627
  The class which should be added or removed.
2564
2628
  @param {Boolean} [newPresent]
2565
2629
  Pass `true` to add the class to the element or `false` to remove it.
@@ -4999,7 +5063,7 @@ It complements [native `Element` methods](https://www.w3schools.com/jsref/dom_ob
4999
5063
  };
5000
5064
 
5001
5065
  CompilerPass.prototype.runCompiler = function(compiler) {
5002
- var i, j, keepValue, len, len1, match, matches, results, value;
5066
+ var base, i, len, match, matches;
5003
5067
  matches = this.select(compiler.selector);
5004
5068
  if (!matches.length) {
5005
5069
  return;
@@ -5015,15 +5079,7 @@ It complements [native `Element` methods](https://www.w3schools.com/jsref/dom_ob
5015
5079
  this.compileOneElement(compiler, match);
5016
5080
  }
5017
5081
  }
5018
- if (keepValue = compiler.keep) {
5019
- value = u.isString(keepValue) ? keepValue : '';
5020
- results = [];
5021
- for (j = 0, len1 = matches.length; j < len1; j++) {
5022
- match = matches[j];
5023
- results.push(match.setAttribute('up-keep', value));
5024
- }
5025
- return results;
5026
- }
5082
+ return typeof (base = up.migrate).postCompile === "function" ? base.postCompile(matches, compiler) : void 0;
5027
5083
  };
5028
5084
 
5029
5085
  CompilerPass.prototype.compileOneElement = function(compiler, element) {
@@ -6653,7 +6709,7 @@ It complements [native `Element` methods](https://www.w3schools.com/jsref/dom_ob
6653
6709
 
6654
6710
 
6655
6711
  /***
6656
- Listens to a ([DOM event](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Events) that originated
6712
+ Listens to a [DOM event](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Events) that originated
6657
6713
  on an element [contained](/up.Layer.prototype.contains) by this layer.
6658
6714
 
6659
6715
  This will ignore events emitted on elements in [descendant](/up.Layer.prototype.descendants) overlays,
@@ -9296,7 +9352,7 @@ It complements [native `Element` methods](https://www.w3schools.com/jsref/dom_ob
9296
9352
 
9297
9353
 
9298
9354
  /***
9299
- Instances of `up.Request` normalizes properties of an [`AJAX request`](/up.request)
9355
+ Instances of `up.Request` normalizes properties of an [AJAX request](/up.request)
9300
9356
  such as the requested URL, form parameters and HTTP method.
9301
9357
 
9302
9358
  You can queue a request using the `up.request()` method:
@@ -10247,7 +10303,7 @@ It complements [native `Element` methods](https://www.w3schools.com/jsref/dom_ob
10247
10303
 
10248
10304
 
10249
10305
  /***
10250
- Instances of `up.Response` describe the server response to an [`AJAX request`](/up.request).
10306
+ Instances of `up.Response` describe the server response to an [AJAX request](/up.request).
10251
10307
 
10252
10308
  \#\#\# Example
10253
10309
 
@@ -10913,7 +10969,8 @@ It complements [native `Element` methods](https://www.w3schools.com/jsref/dom_ob
10913
10969
 
10914
10970
  }).call(this);
10915
10971
  (function() {
10916
- var e, u;
10972
+ var e, u,
10973
+ bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
10917
10974
 
10918
10975
  u = up.util;
10919
10976
 
@@ -10921,6 +10978,8 @@ It complements [native `Element` methods](https://www.w3schools.com/jsref/dom_ob
10921
10978
 
10922
10979
  up.Tether = (function() {
10923
10980
  function Tether(options) {
10981
+ this.sync = bind(this.sync, this);
10982
+ this.scheduleSync = bind(this.scheduleSync, this);
10924
10983
  var base;
10925
10984
  if (typeof (base = up.migrate).handleTetherOptions === "function") {
10926
10985
  base.handleTetherOptions(options);
@@ -11254,6 +11313,9 @@ document.addEventListener('up:modal:open', (event) => {
11254
11313
  })
11255
11314
  ```
11256
11315
 
11316
+ @see up.on
11317
+ @see up.emit
11318
+
11257
11319
  @module up.event
11258
11320
  */
11259
11321
 
@@ -12067,53 +12129,20 @@ There are existing implementations for various web frameworks:
12067
12129
  The timestamp must be explicitely set by the user as an `[up-time]` attribute on the fragment.
12068
12130
  It should indicate the time when the fragment's underlying data was last changed.
12069
12131
 
12070
- Its value is the number of seconds elapsed since the [Unix epoch](https://en.wikipedia.org/wiki/Unix_time).
12132
+ See `[up-time]` for a detailed example.
12071
12133
 
12072
- If no timestamp is known, Unpoly will send a value of zero (`X-Up-Reload-From-Time: 0`).
12073
-
12074
- \#\#\# Example
12134
+ \#\#\# Format
12075
12135
 
12076
- You may timestamp your fragments with an `[up-time]` attribute to indicate when the underlying data
12077
- was last changed. For instance, when the last message in a list was received from December 24th, 1:51:46 PM UTC:
12078
-
12079
- ```html
12080
- <div class="messages" up-time="1608730818">
12081
- ...
12082
- </div>
12083
- ```
12136
+ The time is encoded is the number of seconds elapsed since the [Unix epoch](https://en.wikipedia.org/wiki/Unix_time).
12084
12137
 
12085
- When reloading the `.messages` fragment, Unpoly will echo that timestamp in an `X-Up-Reload-From-Time` header:
12138
+ For instance, a modification date of December 24th, 1:51:46 PM UTC would produce the following header:
12086
12139
 
12087
12140
  ```http
12141
+ X-Up-Target: .unread-count
12088
12142
  X-Up-Reload-From-Time: 1608730818
12089
12143
  ```
12090
12144
 
12091
- \#\# Cheap polling responses
12092
-
12093
- A use case for the `X-Up-Reload-From-Time` header is to avoid rendering unchanged content
12094
- while [polling](/up-poll).
12095
-
12096
- The server can compare the time from the request with the time of the last data update.
12097
- If no more recent data is available, the server can [render nothing](/X-Up-Target):
12098
-
12099
- ```ruby
12100
- class MessagesController < ApplicationController
12101
-
12102
- def index
12103
- if up.reload_from_time == current_user.last_message_at
12104
- up.render_nothing
12105
- else
12106
- @messages = current_user.messages.order(time: :desc).to_a
12107
- render 'index'
12108
- end
12109
- end
12110
-
12111
- end
12112
- ```
12113
-
12114
- Only rendering when needed saves <b>CPU time</b> on your server, which spends most of its response time rendering HTML.
12115
-
12116
- This also reduces the <b>bandwidth cost</b> for a request/response exchange to **~1 KB**.
12145
+ If no timestamp is known, Unpoly will send a value of zero (`X-Up-Reload-From-Time: 0`).
12117
12146
 
12118
12147
  @header X-Up-Reload-From-Time
12119
12148
  @stable
@@ -12505,10 +12534,12 @@ There are existing implementations for various web frameworks:
12505
12534
  Configures strings used in the optional [server protocol](/up.protocol).
12506
12535
 
12507
12536
  @property up.protocol.config
12537
+
12508
12538
  @param {string} [config.csrfHeader='X-CSRF-Token']
12509
12539
  The name of the HTTP header that will include the
12510
12540
  [CSRF token](https://en.wikipedia.org/wiki/Cross-site_request_forgery#Synchronizer_token_pattern)
12511
12541
  for AJAX requests.
12542
+
12512
12543
  @param {string|Function(): string} [config.csrfParam]
12513
12544
  The `name` of the hidden `<input>` used for sending a
12514
12545
  [CSRF token](https://en.wikipedia.org/wiki/Cross-site_request_forgery#Synchronizer_token_pattern) when
@@ -12520,7 +12551,10 @@ There are existing implementations for various web frameworks:
12520
12551
 
12521
12552
  Defaults to the `content` attribute of a `<meta>` tag named `csrf-param`:
12522
12553
 
12523
- <meta name="csrf-param" content="authenticity_token" />
12554
+ ```html
12555
+ <meta name="csrf-param" content="authenticity_token" />
12556
+ ```
12557
+
12524
12558
  @param {string|Function(): string} [config.csrfToken]
12525
12559
  The [CSRF token](https://en.wikipedia.org/wiki/Cross-site_request_forgery#Synchronizer_token_pattern)
12526
12560
  to send for unsafe requests. The token will be sent as either a HTTP header (for AJAX requests)
@@ -12531,7 +12565,10 @@ There are existing implementations for various web frameworks:
12531
12565
 
12532
12566
  Defaults to the `content` attribute of a `<meta>` tag named `csrf-token`:
12533
12567
 
12534
- <meta name='csrf-token' content='secret12345'>
12568
+ ```
12569
+ <meta name='csrf-token' content='secret12345'>
12570
+ ```
12571
+
12535
12572
  @param {string} [config.methodParam='_method']
12536
12573
  The name of request parameter containing the original request method when Unpoly needs to wrap
12537
12574
  the method.
@@ -12724,7 +12761,7 @@ You can activate logging by calling [`up.log.enable()`](/up.log.enable).
12724
12761
  return console.log(logo + text);
12725
12762
  }
12726
12763
  };
12727
- up.on('up:framework:boot', printBanner);
12764
+ up.on('up:app:boot', printBanner);
12728
12765
  up.on('up:framework:reset', reset);
12729
12766
  setEnabled = function(value) {
12730
12767
  sessionStore.set('enabled', value);
@@ -12842,20 +12879,11 @@ You can activate logging by calling [`up.log.enable()`](/up.log.enable).
12842
12879
  Custom JavaScript
12843
12880
  =================
12844
12881
 
12845
- Every app needs a way to pair JavaScript snippets with certain HTML elements,
12846
- in order to integrate libraries or implement custom behavior.
12847
-
12848
- Unpoly lets you organize your JavaScript snippets using [compilers](/up.compiler).
12849
-
12850
- For instance, to activate the [Masonry](http://masonry.desandro.com/) library for every element
12851
- with a `grid` class, use this compiler:
12882
+ The `up.syntax` package lets you pair HTML elements with JavaScript behavior.
12852
12883
 
12853
- up.compiler('.grid', function(element) {
12854
- new Masonry(element, { itemSelector: '.grid--item' })
12855
- })
12856
-
12857
- The compiler function will be called on matching elements when the page loads
12858
- or when a matching fragment is [inserted via AJAX](/up.link) later.
12884
+ @see up.compiler
12885
+ @see [up-data]
12886
+ @see up.macro
12859
12887
 
12860
12888
  @module up.syntax
12861
12889
  */
@@ -12890,14 +12918,17 @@ or when a matching fragment is [inserted via AJAX](/up.link) later.
12890
12918
  Use compilers to activate your custom Javascript behavior on matching
12891
12919
  elements.
12892
12920
 
12893
- You should migrate your [`DOMContentLoaded`](https://api.jquery.com/ready/)
12921
+ You should migrate your [`DOMContentLoaded`](https://developer.mozilla.org/en-US/docs/Web/API/Window/DOMContentLoaded_event)
12894
12922
  callbacks to compilers. This will make sure they run both at page load and
12895
12923
  when a new fragment is inserted later.
12896
- It will also organize your JavaScript snippets by selector of affected elements.
12924
+ See [Making JavaScripts work with fragment updates](/legacy-scripts) for advice
12925
+ on migrating legacy scripts.
12926
+
12927
+ It will also organize your JavaScript snippets by selector.
12897
12928
 
12898
12929
  \#\#\# Example
12899
12930
 
12900
- This jQuery compiler will insert the current time into a
12931
+ This compiler will insert the current time into a
12901
12932
  `<div class='current-time'></div>`:
12902
12933
 
12903
12934
  ```js
@@ -12958,55 +12989,34 @@ or when a matching fragment is [inserted via AJAX](/up.link) later.
12958
12989
 
12959
12990
  An alternative way to register a destructor function is `up.destructor()`.
12960
12991
 
12961
- \#\#\# Attaching structured data
12992
+ \#\#\# Passing parameters to a compiler
12962
12993
 
12963
- In case you want to attach structured data to the event you're observing,
12964
- you can serialize the data to JSON and put it into an `[up-data]` attribute.
12965
- For instance, a container for a [Google Map](https://developers.google.com/maps/documentation/javascript/tutorial)
12966
- might attach the location and names of its marker pins:
12994
+ Use the `[up-data]` attribute to attach structured data to a DOM element.
12995
+ The data will be parsed and passed to your compiler function.
12967
12996
 
12968
- ```html
12969
- <div class='google-map' up-data='[
12970
- { "lat": 48.36, "lng": 10.99, "title": "Friedberg" },
12971
- { "lat": 48.75, "lng": 11.45, "title": "Ingolstadt" }
12972
- ]'></div>
12973
- ```
12997
+ Alternatively your compiler may access attributes for the compiled element
12998
+ via the standard [`Element#getAttribute()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttribute)
12999
+ method.
12974
13000
 
12975
- The JSON will be parsed and handed to your compiler as a second argument:
12976
-
12977
- ```js
12978
- up.compiler('.google-map', function(element, pins) {
12979
- var map = new google.maps.Map(element)
12980
-
12981
- pins.forEach(function(pin) {
12982
- var position = new google.maps.LatLng(pin.lat, pin.lng)
12983
- new google.maps.Marker({
12984
- position: position,
12985
- map: map,
12986
- title: pin.title
12987
- })
12988
- })
12989
- })
12990
- ```
13001
+ Unpoly also provides utility functions to read an element attribute and
13002
+ cast it to a given type:
12991
13003
 
12992
- @see legacy-scripts
13004
+ - `up.element.booleanAttr(element, attr)`
13005
+ - `up.element.numberAttr(element, attr)`
13006
+ - `up.element.jsonAttr(element, attr)`
12993
13007
 
12994
13008
  @function up.compiler
12995
13009
  @param {string} selector
12996
13010
  The selector to match.
12997
13011
  @param {number} [options.priority=0]
12998
13012
  The priority of this compiler.
13013
+
12999
13014
  Compilers with a higher priority are run first.
13000
13015
  Two compilers with the same priority are run in the order they were registered.
13001
13016
  @param {boolean} [options.batch=false]
13002
13017
  If set to `true` and a fragment insertion contains multiple
13003
- elements matching the selector, `compiler` is only called once
13004
- with a jQuery collection containing all matching elements.
13005
- @param {boolean} [options.keep=false]
13006
- If set to `true` compiled fragment will be [persisted](/up-keep) during
13007
- fragment updates.
13008
-
13009
- This has the same effect as setting an `up-keep` attribute on the element.
13018
+ elements matching `selector`, the `compiler` function is only called once
13019
+ with all these elements.
13010
13020
  @param {Function(element, data)} compiler
13011
13021
  The function to call when a matching element is inserted.
13012
13022
 
@@ -13043,10 +13053,12 @@ or when a matching fragment is [inserted via AJAX](/up.link) later.
13043
13053
  This jQuery compiler will insert the current time into a
13044
13054
  `<div class='current-time'></div>`:
13045
13055
 
13046
- up.$compiler('.current-time', function($element) {
13047
- var now = new Date()
13048
- $element.text(now.toString())
13049
- })
13056
+ ```js
13057
+ up.$compiler('.current-time', function($element) {
13058
+ var now = new Date()
13059
+ $element.text(now.toString())
13060
+ })
13061
+ ```
13050
13062
 
13051
13063
  @function up.$compiler
13052
13064
  @param {string} selector
@@ -13070,33 +13082,40 @@ or when a matching fragment is [inserted via AJAX](/up.link) later.
13070
13082
  /***
13071
13083
  Registers a [compiler](/up.compiler) that is run before all other compilers.
13072
13084
 
13073
- Use `up.macro()` to register a compiler that sets multiple Unpoly attributes.
13085
+ A macro lets you set UJS attributes that will be compiled afterwards.
13086
+
13087
+ If you want default attributes for *every* link and form, consider customizing your
13088
+ [navigation options](/navigation).
13074
13089
 
13075
13090
  \#\#\# Example
13076
13091
 
13077
13092
  You will sometimes find yourself setting the same combination of UJS attributes again and again:
13078
13093
 
13079
- <a href="/page1" up-target=".content" up-transition="cross-fade" up-duration="300">Page 1</a>
13080
- <a href="/page2" up-target=".content" up-transition="cross-fade" up-duration="300">Page 2</a>
13081
- <a href="/page3" up-target=".content" up-transition="cross-fade" up-duration="300">Page 3</a>
13094
+ ```html
13095
+ <a href="/page1" up-layer="new modal" up-class="warning" up-animation="shake">Page 1</a>
13096
+ <a href="/page1" up-layer="new modal" up-class="warning" up-animation="shake">Page 1</a>
13097
+ <a href="/page1" up-layer="new modal" up-class="warning" up-animation="shake">Page 1</a>
13098
+ ```
13082
13099
 
13083
- We would much rather define a new `[content-link]` attribute that let's us
13100
+ We would much rather define a new `[smooth-link]` attribute that let's us
13084
13101
  write the same links like this:
13085
13102
 
13086
- <a href="/page1" content-link>Page 1</a>
13087
- <a href="/page2" content-link>Page 2</a>
13088
- <a href="/page3" content-link>Page 3</a>
13103
+ ```html
13104
+ <a href="/page1" smooth-link>Page 1</a>
13105
+ <a href="/page2" smooth-link>Page 2</a>
13106
+ <a href="/page3" smooth-link>Page 3</a>
13107
+ ```
13089
13108
 
13090
13109
  We can define the `[content-link]` attribute by registering a macro that
13091
13110
  sets the `[up-target]`, `[up-transition]` and `[up-duration]` attributes for us:
13092
13111
 
13093
- up.macro('[content-link]', function(link) {
13094
- link.setAttribute('up-target', '.content')
13095
- link.setAttribute('up-transition', 'cross-fade')
13096
- link.setAttribute('up-duration', '300')
13097
- })
13098
-
13099
- Examples for built-in macros are [`a[up-dash]`](/a-up-dash) and [`[up-expand]`](/up-expand).
13112
+ ```
13113
+ up.macro('[smooth-link]', function(link) {
13114
+ link.setAttribute('up-target', '.content')
13115
+ link.setAttribute('up-transition', 'cross-fade')
13116
+ link.setAttribute('up-duration', '300')
13117
+ })
13118
+ ```
13100
13119
 
13101
13120
  @function up.macro
13102
13121
  @param {string} selector
@@ -13129,13 +13148,15 @@ or when a matching fragment is [inserted via AJAX](/up.link) later.
13129
13148
 
13130
13149
  \#\#\# Example
13131
13150
 
13132
- up.$macro('[content-link]', function($link) {
13133
- $link.attr(
13134
- 'up-target': '.content',
13135
- 'up-transition': 'cross-fade',
13136
- 'up-duration':'300'
13137
- )
13138
- })
13151
+ ```js
13152
+ up.$macro('[content-link]', function($link) {
13153
+ $link.attr(
13154
+ 'up-target': '.content',
13155
+ 'up-transition': 'cross-fade',
13156
+ 'up-duration':'300'
13157
+ )
13158
+ })
13159
+ ```
13139
13160
 
13140
13161
  @function up.$macro
13141
13162
  @param {string} selector
@@ -13197,6 +13218,7 @@ or when a matching fragment is [inserted via AJAX](/up.link) later.
13197
13218
 
13198
13219
  /***
13199
13220
  Applies all compilers on the given element and its descendants.
13221
+
13200
13222
  Unlike [`up.hello()`](/up.hello), this doesn't emit any events.
13201
13223
 
13202
13224
  @function up.syntax.compile
@@ -13225,8 +13247,8 @@ or when a matching fragment is [inserted via AJAX](/up.link) later.
13225
13247
  })
13226
13248
  ```
13227
13249
 
13228
- An alternative way to register a destructor function is to `return`
13229
- it from your compiler function.
13250
+ An alternative way to register a destructor function is to
13251
+ [`return` it from your compiler function](/up.compiler#cleaning-up-after-yourself).
13230
13252
 
13231
13253
  @function up.destructor
13232
13254
  @param {Element} element
@@ -13250,6 +13272,7 @@ or when a matching fragment is [inserted via AJAX](/up.link) later.
13250
13272
 
13251
13273
  /***
13252
13274
  Runs any destructor on the given fragment and its descendants in the same layer.
13275
+
13253
13276
  Unlike [`up.destroy()`](/up.destroy), this does not emit any events
13254
13277
  and does not remove the element from the DOM.
13255
13278
 
@@ -13268,20 +13291,23 @@ or when a matching fragment is [inserted via AJAX](/up.link) later.
13268
13291
  };
13269
13292
 
13270
13293
  /***
13271
- Checks if the given element has an [`up-data`](/up-data) attribute.
13272
- If yes, parses the attribute value as JSON and returns the parsed object.
13294
+ Returns the given element's `[up-data]`, parsed as a JavaScript object.
13273
13295
 
13274
- Returns `undefined` if the element has no `up-data` attribute.
13296
+ Returns `undefined` if the element has no `[up-data]` attribute.
13275
13297
 
13276
13298
  \#\#\# Example
13277
13299
 
13278
13300
  You have an element with JSON data serialized into an `up-data` attribute:
13279
13301
 
13280
- <span class='person' up-data='{ "age": 18, "name": "Bob" }'>Bob</span>
13302
+ ```html
13303
+ <span class='person' up-data='{ "age": 18, "name": "Bob" }'>Bob</span>
13304
+ ```
13281
13305
 
13282
13306
  Calling `up.syntax.data()` will deserialize the JSON string into a JavaScript object:
13283
13307
 
13284
- up.syntax.data('.person') // returns { age: 18, name: 'Bob' }
13308
+ ```js
13309
+ up.syntax.data('.person') // returns { age: 18, name: 'Bob' }
13310
+ ```
13285
13311
 
13286
13312
  @function up.data
13287
13313
  @param {string|Element|jQuery} element
@@ -13294,39 +13320,49 @@ or when a matching fragment is [inserted via AJAX](/up.link) later.
13294
13320
  */
13295
13321
 
13296
13322
  /***
13297
- If an element with an `up-data` attribute enters the DOM,
13323
+ Attaches structured data to an element, to be consumed by a compiler.
13324
+
13325
+ If an element with an `[up-data]` attribute enters the DOM,
13298
13326
  Unpoly will parse the JSON and pass the resulting object to any matching
13299
- [`up.compiler()`](/up.compiler) handlers.
13327
+ [`up.compiler()`](/up.compiler) functions.
13328
+
13329
+ \#\#\# Example
13300
13330
 
13301
13331
  For instance, a container for a [Google Map](https://developers.google.com/maps/documentation/javascript/tutorial)
13302
13332
  might attach the location and names of its marker pins:
13303
13333
 
13304
- <div class='google-map' up-data='[
13305
- { "lat": 48.36, "lng": 10.99, "title": "Friedberg" },
13306
- { "lat": 48.75, "lng": 11.45, "title": "Ingolstadt" }
13307
- ]'></div>
13334
+ ```html
13335
+ <div class='google-map' up-data='[
13336
+ { "lat": 48.36, "lng": 10.99, "title": "Friedberg" },
13337
+ { "lat": 48.75, "lng": 11.45, "title": "Ingolstadt" }
13338
+ ]'></div>
13339
+ ```
13308
13340
 
13309
13341
  The JSON will be parsed and handed to your compiler as a second argument:
13310
13342
 
13311
- up.compiler('.google-map', function(element, pins) {
13312
- var map = new google.maps.Map(element)
13313
- pins.forEach(function(pin) {
13314
- var position = new google.maps.LatLng(pin.lat, pin.lng)
13315
- new google.maps.Marker({
13316
- position: position,
13317
- map: map,
13318
- title: pin.title
13319
- })
13320
- })
13343
+ ```js
13344
+ up.compiler('.google-map', function(element, pins) {
13345
+ var map = new google.maps.Map(element)
13346
+ pins.forEach(function(pin) {
13347
+ var position = new google.maps.LatLng(pin.lat, pin.lng)
13348
+ new google.maps.Marker({
13349
+ position: position,
13350
+ map: map,
13351
+ title: pin.title
13321
13352
  })
13353
+ })
13354
+ })
13355
+ ```
13322
13356
 
13323
13357
  Similarly, when an event is triggered on an element annotated with
13324
13358
  [`up-data`], the parsed object will be passed to any matching
13325
13359
  [`up.on()`](/up.on) handlers.
13326
13360
 
13327
- up.on('click', '.google-map', function(event, element, pins) {
13328
- console.log("There are %d pins on the clicked map", pins.length)
13329
- })
13361
+ ```js
13362
+ up.on('click', '.google-map', function(event, element, pins) {
13363
+ console.log("There are %d pins on the clicked map", pins.length)
13364
+ })
13365
+ ```
13330
13366
 
13331
13367
  @selector [up-data]
13332
13368
  @param up-data
@@ -13383,6 +13419,9 @@ In an Unpoly app, every page has an URL.
13383
13419
 
13384
13420
  [Fragment updates](/up.link) automatically update the URL.
13385
13421
 
13422
+ @see up.history.location
13423
+ @see up:location:changed
13424
+
13386
13425
  @module up.history
13387
13426
  */
13388
13427
 
@@ -13699,18 +13738,33 @@ In an Unpoly app, every page has an URL.
13699
13738
 
13700
13739
 
13701
13740
  /***
13702
- Fragment update API
13703
- ===================
13704
-
13705
- The `up.fragment` module exposes a high-level Javascript API to [update](/up.replace) or
13706
- [destroy](/up.destroy) page fragments.
13741
+ Fragment API
13742
+ ===========
13743
+
13744
+ The `up.fragment` module offers a high-level JavaScript API to work with DOM elements.
13707
13745
 
13708
- Fragments are [compiled](/up.compiler) elements that can be updated from a server URL.
13709
- They also exist on a layer (page, modal, popup).
13746
+ A fragment is an element with some additional properties that are useful in the context of
13747
+ a server-rendered web application:
13710
13748
 
13711
- Most of Unpoly's functionality (like [fragment links](/up.link) or [modals](/up.modal))
13712
- is built from `up.fragment` functions. You may use them to extend Unpoly from your
13713
- [custom Javascript](/up.syntax).
13749
+ - Fragments are [identified by a CSS selector](/up.fragment.toTarget), like a `.class` or `#id`.
13750
+ - Fragments are usually updated by a [link](/a-up-follow) for [form](/form-up-submits) that targets their selector.
13751
+ When the server renders HTML with a matching element, the fragment is swapped with a new version.
13752
+ - As fragments enter the page they are automatically [compiled](/up.compiler) to activate JavaScript behavior.
13753
+ - Fragment changes may be [animated](/up.motion).
13754
+ - Fragments are placed on a [layer](/up.layer) that is isolated from other layers.
13755
+ Unpoly functions will only see or change fragments from the [current layer](/up.layer.current)
13756
+ unless you [explicitly target another layer](/layer-option).
13757
+ - Fragments [know the URL from where they were loaded](/up.source).
13758
+ They can be [reloaded](/up.reload) or [polled periodically](/up-polled).
13759
+
13760
+ For low-level DOM utilities that complement the browser's native API, see `up.element`.
13761
+
13762
+ @see up.render
13763
+ @see up.navigate
13764
+ @see up.destroy
13765
+ @see up.reload
13766
+ @see up.fragment.get
13767
+ @see up.hello
13714
13768
 
13715
13769
  @module up.fragment
13716
13770
  */
@@ -13865,6 +13919,74 @@ In an Unpoly app, every page has an URL.
13865
13919
  return e.closestAttr(element, 'up-time') || '0';
13866
13920
  };
13867
13921
 
13922
+ /***
13923
+ Sets the time when the fragment's underlying data was last changed.
13924
+
13925
+ This can be used to avoid rendering unchanged HTML when [reloading](/up.reload)
13926
+ a fragment. This saves <b>CPU time</b> and reduces the <b>bandwidth cost</b> for a
13927
+ request/response exchange to **~1 KB**.
13928
+
13929
+ \#\# Example
13930
+
13931
+ Let's say we display a list of recent messages.
13932
+ We use the `[up-poll]` attribute to reload the `.messages` fragment every 30 seconds:
13933
+
13934
+ ```html
13935
+ <div class="messages" up-poll>
13936
+ ...
13937
+ </div>
13938
+ ```
13939
+
13940
+ The list is now always up to date. But most of the time there will not be new messages,
13941
+ and we waste resources sending the same unchanged HTML from the server.
13942
+
13943
+ We can improve this by setting an `[up-time]` attribute and the message list.
13944
+ The attribute value is the time of the most recent message.
13945
+
13946
+ The time is encoded as the number of seconds since [Unix epoch](https://en.wikipedia.org/wiki/Unix_time).
13947
+ When, for instance, the last message in a list was received from December 24th, 1:51:46 PM UTC,
13948
+ we use the following HTML:
13949
+
13950
+ ```html
13951
+ <div class="messages" up-time="1608730818" up-poll>
13952
+ ...
13953
+ </div>
13954
+ ```
13955
+
13956
+ When reloading Unpoly will echo the `[up-time]` timestamp in an `X-Up-Reload-From-Time` header:
13957
+
13958
+ ```http
13959
+ X-Up-Reload-From-Time: 1608730818
13960
+ ```
13961
+
13962
+ The server can compare the time from the request with the time of the last data update.
13963
+ If no more recent data is available, the server can render nothing and respond with
13964
+ an [`X-Up-Target: :none`](/X-Up-Target) header.
13965
+
13966
+ Here is an example with [unpoly-rails](https://unpoly.com/install/rails):
13967
+
13968
+ ```ruby
13969
+ class MessagesController < ApplicationController
13970
+
13971
+ def index
13972
+ if up.reload_from_time == current_user.last_message_at
13973
+ up.render_nothing
13974
+ else
13975
+ @messages = current_user.messages.order(time: :desc).to_a
13976
+ render 'index'
13977
+ end
13978
+ end
13979
+
13980
+ end
13981
+ ```
13982
+
13983
+ @selector [up-time]
13984
+ @param {string} up-time
13985
+ The number of seconds between the [Unix epoch](https://en.wikipedia.org/wiki/Unix_time).
13986
+ and the time when the element's underlying data was last changed.
13987
+ @experimental
13988
+ */
13989
+
13868
13990
  /***
13869
13991
  Sets this element's source URL for [reloading](/up.reload) and [polling](/up-poll)
13870
13992
 
@@ -13886,7 +14008,7 @@ In an Unpoly app, every page has an URL.
13886
14008
  </div>
13887
14009
 
13888
14010
  @selector [up-source]
13889
- @param {String} up-source
14011
+ @param {string} up-source
13890
14012
  The URL from which to reload this element.
13891
14013
  @stable
13892
14014
  */
@@ -14064,7 +14186,7 @@ In an Unpoly app, every page has an URL.
14064
14186
  If set to `false`, the history will remain unchanged.
14065
14187
 
14066
14188
  [Overlays](/up.layer) will only change the browser URL and window title if the overlay
14067
- has [visible history](/up.layer.historyVisible), even with `{ history: true }`.
14189
+ has [visible history](/up.layer.historyVisible), even when `{ history: true }` is passed.
14068
14190
 
14069
14191
  @param {string} [options.title]
14070
14192
  An explicit document title to use after rendering.
@@ -14687,7 +14809,7 @@ In an Unpoly app, every page has an URL.
14687
14809
  - The [`up.element.all()`](/up.element.get) function simply returns the all elements matching a selector
14688
14810
  without further filtering.
14689
14811
 
14690
- @function up.fragment.get
14812
+ @function up.fragment.all
14691
14813
 
14692
14814
  @param {Element|jQuery} [root=document]
14693
14815
  The root element for the search. Only the root's children will be matched.
@@ -14922,7 +15044,8 @@ In an Unpoly app, every page has an URL.
14922
15044
 
14923
15045
  \#\#\# Skipping updates when nothing changed
14924
15046
 
14925
- TODO: Document [up-time] and X-Up-Reload-From-Time (currently both documented in `X-Up-Reload-From-Time`).
15047
+ You may use the `[up-time]` attribute to avoid rendering unchanged HTML when reloading
15048
+ a fragment. See `[up-time]` for a detailed example.
14926
15049
 
14927
15050
  @function up.reload
14928
15051
  @param {string|Element|jQuery} [target]
@@ -15357,30 +15480,15 @@ In an Unpoly app, every page has an URL.
15357
15480
  Scrolling viewports
15358
15481
  ===================
15359
15482
 
15360
- The `up.viewport` module controls the scroll position of scrollable containers ("viewports").
15483
+ The `up.viewport` module controls the scroll position and focus within scrollable containers ("viewports").
15361
15484
 
15362
15485
  The default viewport for any web application is the main document. An application may
15363
15486
  define additional viewports by giving the CSS property `{ overflow-y: scroll }` to any `<div>`.
15364
15487
 
15488
+ Also see documentation for the [scroll option](/scroll-option) and [focus option](focus-option).
15365
15489
 
15366
- \#\#\# Revealing new content
15367
-
15368
- When following a [link to a fragment](/a-up-follow) Unpoly will automatically
15369
- scroll the document's viewport to [reveal](/up.viewport) the updated content.
15370
-
15371
- You should [make Unpoly aware](/up.viewport.config#config.fixedTop) of fixed elements in your
15372
- layout, such as navigation bars or headers. Unpoly will respect these sticky
15373
- elements when [revealing updated fragments](/up.reveal).
15374
-
15375
- You should also [tell Unpoly](/up.viewport.config#config.viewportSelectors) when your application has more than one viewport,
15376
- so Unpoly can pick the right viewport to scroll for each fragment update.
15377
-
15378
-
15379
- \#\#\# Bootstrap integration
15380
-
15381
- When using Bootstrap integration (`unpoly-bootstrap3.js` and `unpoly-bootstrap3.css`)
15382
- Unpoly will automatically be aware of sticky Bootstrap components such as
15383
- [fixed navbar](https://getbootstrap.com/examples/navbar-fixed-top/).
15490
+ @see up.reveal
15491
+ @see [up-fixed=top]
15384
15492
 
15385
15493
  @module up.viewport
15386
15494
  */
@@ -15389,29 +15497,31 @@ Unpoly will automatically be aware of sticky Bootstrap components such as
15389
15497
  var slice = [].slice;
15390
15498
 
15391
15499
  up.viewport = (function() {
15392
- var absolutize, allSelector, anchoredRight, autofocus, closest, config, doFocus, e, f, firstHashTarget, fixedElements, getAll, getAround, getRoot, getScrollTops, getSubtree, isNativelyFocusable, isRoot, makeFocusable, parseOptions, pureHash, reset, resetScroll, restoreScroll, reveal, revealHash, rootHasReducedWidthFromScrollbar, rootHeight, rootOverflowElement, rootSelector, rootWidth, saveScroll, scroll, scrollTopKey, scrollTops, scrollbarWidth, scrollingController, setScrollTops, tryFocus, u, userScrolled, wasChosenAsOverflowingElement;
15500
+ var absolutize, allSelector, anchoredRight, closest, config, doFocus, e, f, firstHashTarget, fixedElements, getAll, getAround, getRoot, getScrollTops, getSubtree, isNativelyFocusable, isRoot, makeFocusable, parseOptions, pureHash, reset, resetScroll, restoreScroll, reveal, revealHash, rootHasReducedWidthFromScrollbar, rootHeight, rootOverflowElement, rootSelector, rootWidth, saveScroll, scroll, scrollTopKey, scrollTops, scrollbarWidth, scrollingController, setScrollTops, tryFocus, u, userScrolled, wasChosenAsOverflowingElement;
15393
15501
  u = up.util;
15394
15502
  e = up.element;
15395
15503
  f = up.fragment;
15396
15504
 
15397
15505
  /***
15398
- Configures the application layout.
15506
+ Configures defaults for scrolling.
15399
15507
 
15400
15508
  @property up.viewport.config
15401
15509
  @param {Array} [config.viewportSelectors]
15402
- An array of CSS selectors that find viewports
15403
- (containers that scroll their contents).
15510
+ An array of CSS selectors that match viewports.
15404
15511
  @param {Array} [config.fixedTop]
15405
15512
  An array of CSS selectors that find elements fixed to the
15406
15513
  top edge of the screen (using `position: fixed`).
15514
+
15407
15515
  See [`[up-fixed="top"]`](/up-fixed-top) for details.
15408
15516
  @param {Array} [config.fixedBottom]
15409
- An array of CSS selectors that find elements fixed to the
15517
+ An array of CSS selectors that match elements fixed to the
15410
15518
  bottom edge of the screen (using `position: fixed`).
15519
+
15411
15520
  See [`[up-fixed="bottom"]`](/up-fixed-bottom) for details.
15412
15521
  @param {Array} [config.anchoredRight]
15413
15522
  An array of CSS selectors that find elements anchored to the
15414
15523
  right edge of the screen (using `right:0` with `position: fixed` or `position: absolute`).
15524
+
15415
15525
  See [`[up-anchored="right"]`](/up-anchored-right) for details.
15416
15526
  @param {number} [config.revealSnap]
15417
15527
  When [revealing](/up.reveal) elements, Unpoly will scroll an viewport
@@ -15525,19 +15635,9 @@ Unpoly will automatically be aware of sticky Bootstrap components such as
15525
15635
  };
15526
15636
 
15527
15637
  /***
15528
- Scroll's the given element's viewport so the first rows of the
15638
+ Scrolls the given element's viewport so the first rows of the
15529
15639
  element are visible for the user.
15530
15640
 
15531
- \#\#\# How Unpoly finds the viewport
15532
-
15533
- The viewport (the container that is going to be scrolled)
15534
- is the closest parent of the element that is either:
15535
-
15536
- - the currently open [modal](/up.modal)
15537
- - an element with the attribute `[up-viewport]`
15538
- - the `<body>` element
15539
- - an element matching the selector you have configured using `up.viewport.config.viewportSelectors.push('my-custom-selector')`
15540
-
15541
15641
  \#\#\# Fixed elements obstructing the viewport
15542
15642
 
15543
15643
  Many applications have a navigation bar fixed to the top or bottom,
@@ -15545,14 +15645,16 @@ Unpoly will automatically be aware of sticky Bootstrap components such as
15545
15645
 
15546
15646
  You can make `up.reveal()` aware of these fixed elements
15547
15647
  so it can scroll the viewport far enough so the revealed element is fully visible.
15548
- To make `up.reveal()` aware fixed elements you can either:
15648
+ To make `up.reveal()` aware of fixed elements you can either:
15549
15649
 
15550
15650
  - give the element an attribute [`up-fixed="top"`](/up-fixed-top) or [`up-fixed="bottom"`](up-fixed-bottom)
15551
15651
  - [configure default options](/up.viewport.config) for `fixedTop` or `fixedBottom`
15552
15652
 
15553
15653
  @function up.reveal
15654
+
15554
15655
  @param {string|Element|jQuery} element
15555
15656
  The element to reveal.
15657
+
15556
15658
  @param {number} [options.scrollSpeed=1]
15557
15659
  The speed of the scrolling motion when scrolling with `{ behavior: 'smooth' }`.
15558
15660
 
@@ -15560,6 +15662,7 @@ Unpoly will automatically be aware of sticky Bootstrap components such as
15560
15662
  [native smooth scrolling](https://developer.mozilla.org/en-US/docs/Web/API/ScrollToOptions/behavior).
15561
15663
 
15562
15664
  Defaults to `up.viewport.config.scrollSpeed`.
15665
+
15563
15666
  @param {string} [options.revealSnap]
15564
15667
  When the the revealed element would be closer to the viewport's top edge
15565
15668
  than this value, Unpoly will scroll the viewport to the top.
@@ -15567,35 +15670,40 @@ Unpoly will automatically be aware of sticky Bootstrap components such as
15567
15670
  Set to `0` to disable snapping.
15568
15671
 
15569
15672
  Defaults to `up.viewport.config.revealSnap`.
15673
+
15570
15674
  @param {string|Element|jQuery} [options.viewport]
15571
15675
  The scrolling element to scroll.
15572
15676
 
15573
15677
  Defaults to the [given element's viewport](/up.viewport.closest).
15678
+
15574
15679
  @param {boolean} [options.top]
15575
15680
  Whether to scroll the viewport so that the first element row aligns
15576
15681
  with the top edge of the viewport.
15577
15682
 
15578
15683
  Defaults to `up.viewport.config.revealTop`.
15684
+
15579
15685
  @param {string}[options.behavior='auto']
15580
15686
  When set to `'auto'`, this will immediately scroll to the new position.
15581
15687
 
15582
15688
  When set to `'smooth'`, this will scroll smoothly to the new position.
15689
+
15583
15690
  @param {number}[options.speed]
15584
15691
  The speed of the scrolling motion when scrolling with `{ behavior: 'smooth' }`.
15585
15692
 
15586
15693
  Defaults to `up.viewport.config.scrollSpeed`.
15694
+
15587
15695
  @param {number} [options.padding]
15588
15696
  The desired padding between the revealed element and the
15589
15697
  closest [viewport](/up.viewport) edge (in pixels).
15590
15698
 
15591
15699
  Defaults to `up.viewport.config.revealPadding`.
15700
+
15592
15701
  @param {number|boolean} [options.snap]
15593
15702
  Whether to snap to the top of the viewport if the new scroll position
15594
15703
  after revealing the element is close to the top edge.
15595
15704
 
15596
15705
  Defaults to `up.viewport.config.revealSnap`.
15597
- @param {boolean} [options.peel=true]
15598
- Whether to close overlays obscuring the layer of `element`.
15706
+
15599
15707
  @return {Promise}
15600
15708
  A promise that fulfills when the element is revealed.
15601
15709
 
@@ -15604,13 +15712,12 @@ Unpoly will automatically be aware of sticky Bootstrap components such as
15604
15712
 
15605
15713
  When the scrolling is not animated, the promise will fulfill
15606
15714
  in the next [microtask](https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/).
15715
+
15607
15716
  @stable
15608
15717
  */
15609
15718
  reveal = function(element, options) {
15610
15719
  var motion;
15611
- options = u.options(options, {
15612
- peel: true
15613
- });
15720
+ options = u.options(options);
15614
15721
  element = f.get(element, options);
15615
15722
  if (!(options.layer = up.layer.get(element))) {
15616
15723
  return up.error.failed.async('Cannot reveal a detached element');
@@ -15623,7 +15730,19 @@ Unpoly will automatically be aware of sticky Bootstrap components such as
15623
15730
  };
15624
15731
 
15625
15732
  /***
15626
- TODO: Docs
15733
+ Focuses the given element.
15734
+
15735
+ Focusing an element will also [reveal](/up.reveal) it, unless `{ preventScroll: true }` is passed.
15736
+
15737
+ @function up.focus
15738
+
15739
+ @param {string|Element|jQuery} element
15740
+ The element to focus.
15741
+
15742
+ @param {[options.preventScroll=false]}
15743
+ Whether to prevent changes to the acroll position.
15744
+
15745
+ @experimental
15627
15746
  */
15628
15747
  doFocus = function(element, options) {
15629
15748
  var oldScrollTop, viewport;
@@ -15648,13 +15767,6 @@ Unpoly will automatically be aware of sticky Bootstrap components such as
15648
15767
  doFocus(element, options);
15649
15768
  return element === document.activeElement;
15650
15769
  };
15651
- autofocus = function(element, options) {
15652
- var autofocusElement;
15653
- if (autofocusElement = e.subtree(element, '[autofocus]')[0]) {
15654
- doDocus(autofocusElement, options);
15655
- return true;
15656
- }
15657
- };
15658
15770
  isNativelyFocusable = function(element) {
15659
15771
  return e.matches(element, 'a[href], button, textarea, input, select');
15660
15772
  };
@@ -15724,6 +15836,9 @@ Unpoly will automatically be aware of sticky Bootstrap components such as
15724
15836
  Returns a list of all the viewports contained within the
15725
15837
  given selector or element.
15726
15838
 
15839
+ If the given element is itself a viewport, the element is included
15840
+ in the returned list.
15841
+
15727
15842
  @function up.viewport.subtree
15728
15843
  @param {string|Element|jQuery} target
15729
15844
  @param {Object} options
@@ -15916,30 +16031,11 @@ Unpoly will automatically be aware of sticky Bootstrap components such as
15916
16031
 
15917
16032
  The scroll positions will be associated with the current URL.
15918
16033
  They can later be restored by calling [`up.viewport.restoreScroll()`](/up.viewport.restoreScroll)
15919
- at the same URL, or by following a link with an [`[up-restore-scroll]`](/a-up-follow#up-restore-scroll)
16034
+ at the same URL, or by following a link with an [`[scroll="restore"]`](/a-up-follow#up-restore-scroll)
15920
16035
  attribute.
15921
16036
 
15922
- Unpoly automatically saves scroll positions before a [fragment update](/up.replace)
15923
- you will rarely need to call this function yourself.
15924
-
15925
- \#\#\# Examples
15926
-
15927
- Should you need to save the current scroll positions outside of a [fragment update](/up.replace),
15928
- you may call:
15929
-
15930
- up.viewport.saveScroll()
15931
-
15932
- Instead of saving the current scroll positions for the current URL, you may also pass another
15933
- url or vertical scroll positionsfor each viewport:
15934
-
15935
- up.viewport.saveScroll({
15936
- url: '/inbox',
15937
- tops: {
15938
- 'body': 0,
15939
- '.sidebar', 100,
15940
- '.main', 320
15941
- }
15942
- })
16037
+ Unpoly automatically saves scroll positions before [navigating](/navigation).
16038
+ You will rarely need to call this function yourself.
15943
16039
 
15944
16040
  @function up.viewport.saveScroll
15945
16041
  @param {string} [options.location]
@@ -16266,7 +16362,6 @@ Unpoly will automatically be aware of sticky Bootstrap components such as
16266
16362
  absolutize: absolutize,
16267
16363
  focus: doFocus,
16268
16364
  tryFocus: tryFocus,
16269
- autofocus: autofocus,
16270
16365
  makeFocusable: makeFocusable
16271
16366
  });
16272
16367
  })();
@@ -16310,6 +16405,11 @@ and [predefined animations](/up.animate#named-animations).
16310
16405
  You can define custom animations using `up.transition()` and
16311
16406
  `up.animation()`.
16312
16407
 
16408
+ @see up.animation
16409
+ @see up.animate
16410
+ @see up.transition
16411
+ @see up.morph
16412
+
16313
16413
  @module up.motion
16314
16414
  */
16315
16415
 
@@ -16774,7 +16874,7 @@ You can define custom animations using `up.transition()` and
16774
16874
  If you choose to *not* use `up.animate()` and roll your own
16775
16875
  animation code instead, your code must honor the following contract:
16776
16876
 
16777
- 1. It must honor the options `{ duration, easing }` if given
16877
+ 1. It must honor the options `{ duration, easing }`, if given.
16778
16878
  2. It must *not* remove any of the given elements from the DOM.
16779
16879
  3. It returns a promise that is fulfilled when the transition has ended
16780
16880
  4. If during the animation an event `up:motion:finish` is emitted on
@@ -16997,6 +17097,10 @@ You can define custom animations using `up.transition()` and
16997
17097
  - [Instantaneous feedback for links that are currently loading](/a.up-active)
16998
17098
  - [Follow links on `mousedown` instead of `click`](/a-up-instant)
16999
17099
 
17100
+ @see up.request
17101
+ @see up.Request
17102
+ @see up.Response
17103
+
17000
17104
  @module up.network
17001
17105
  */
17002
17106
 
@@ -17725,15 +17829,30 @@ You can define custom animations using `up.transition()` and
17725
17829
  Layers
17726
17830
  ======
17727
17831
 
17728
- TODO
17832
+ Unpoly allows you to [open page fragments in an overlay](/opening-overlays). Overlays may be stacked infinitely.
17833
+
17834
+ A variety of [overlay modes](/layer-terminology) are supported,
17835
+ such as modal dialogs, popup overlays or drawers. You may [customize their appearance and behavior](/customizing-overlays).
17836
+
17837
+ Layers are isolated, meaning a screen in one layer will not accidentally see elements
17838
+ or events from another layer. For instance, [fragment links](/up.link) will only update elements from the [current layer](/up.layer.current)
17839
+ unless you [explicitly target another layer](/layer-option).
17840
+
17841
+ Overlays allow you to break up a complex screen into [subinteractions](/subinteractions).
17842
+ Subinteractions take place in overlays and may span one or many pages. The original screen remains open in the background.
17843
+ Once the subinteraction is *done*, the overlay is closed and a result value is communicated back to the parent layer.
17844
+
17845
+ @see a[up-layer=new]
17846
+ @see up.layer.current
17847
+ @see up.layer.on
17848
+ @see up.layer.ask
17729
17849
 
17730
17850
  @module up.layer
17731
17851
  */
17732
17852
 
17733
17853
  up.layer = (function() {
17734
- var LAYER_CLASSES, OVERLAY_CLASSES, OVERLAY_MODES, anySelector, api, ask, build, closeCallbackAttr, config, handlers, isOverlayMode, mainTargets, modeConfigs, normalizeOptions, open, openCallbackAttr, optionToString, reset, stack;
17854
+ var LAYER_CLASSES, OVERLAY_CLASSES, anySelector, api, ask, build, closeCallbackAttr, config, handlers, mainTargets, modeConfigs, normalizeOptions, open, openCallbackAttr, optionToString, reset, stack;
17735
17855
  OVERLAY_CLASSES = [up.Layer.Modal, up.Layer.Popup, up.Layer.Drawer, up.Layer.Cover];
17736
- OVERLAY_MODES = u.map(OVERLAY_CLASSES, 'mode');
17737
17856
  LAYER_CLASSES = [up.Layer.Root].concat(OVERLAY_CLASSES);
17738
17857
 
17739
17858
  /***
@@ -17931,16 +18050,17 @@ You can define custom animations using `up.transition()` and
17931
18050
  });
17932
18051
 
17933
18052
  /***
17934
- TODO: Docs
18053
+ A list of layers that are currently open.
18054
+
18055
+ The first element in the list is the [root layer](/up.layer.root).
18056
+ The last element is the [frontmost layer](/up.layer.front).
17935
18057
 
17936
- @function up.layer.stack
18058
+ @property up.layer.stack
18059
+ @param {List<up.Layer>} stack
17937
18060
  @stable
17938
18061
  */
17939
18062
  stack = null;
17940
18063
  handlers = [];
17941
- isOverlayMode = function(mode) {
17942
- return u.contains(OVERLAY_MODES, mode);
17943
- };
17944
18064
  mainTargets = function(mode) {
17945
18065
  return u.flatMap(modeConfigs(mode), 'mainTargets');
17946
18066
  };
@@ -18177,13 +18297,38 @@ You can define custom animations using `up.transition()` and
18177
18297
  };
18178
18298
 
18179
18299
  /***
18180
- TODO: Docs
18181
- TODO: Document that listeners may manipulate options
18182
- TODO: Document that it's emitted on the document
18300
+ This event is emitted before an overlay is opened.
18301
+
18302
+ The overlay is not yet part of the [layer stack](/up.layer.stack) and has not yet been placed
18303
+ in the DOM. Listeners may prevent this event to prevent the overlay from opening.
18304
+
18305
+ The event is emitted on the `document`.
18306
+
18307
+ \#\#\# Changing layer options
18308
+
18309
+ Listeners may inspect and manipulate options for the overlay that is about to open.
18310
+
18311
+ For example, to give overlays the CSS class `.warning` if the initial URL contains
18312
+ the word `"confirm"`:
18313
+
18314
+ ```js
18315
+ up.on('up:layer:open', function(event) {
18316
+ if (event.layerOptions.url.includes('confirm')) {
18317
+ event.layerOptions.class = 'warning'
18318
+ }
18319
+ })
18320
+ ```
18183
18321
 
18184
18322
  @event up:layer:open
18185
18323
  @param {Object} event.layerOptions
18324
+ Options for the overlay that is about to open.
18325
+
18326
+ Listeners may inspect and change the options.
18327
+ All options for `up.layer.open()` may be used.
18186
18328
  @param {Element} event.origin
18329
+ The link element that is opening the overlay.
18330
+ @param event.preventDefault()
18331
+ Event listeners may call this method to prevent the overlay from opening.
18187
18332
  @stable
18188
18333
  */
18189
18334
 
@@ -18570,7 +18715,7 @@ You can define custom animations using `up.transition()` and
18570
18715
 
18571
18716
  If no overlay is open, an empty array is returned.
18572
18717
 
18573
- @function up.layer.overlays
18718
+ @property up.layer.overlays
18574
18719
  @param {Array<up.Layer>} overlays
18575
18720
  @stable
18576
18721
  */
@@ -18595,9 +18740,9 @@ You can define custom animations using `up.transition()` and
18595
18740
  Afterwards the only remaining layer will be the [root layer](/up.layer.root).
18596
18741
 
18597
18742
  @function up.layer.dismissOverlays
18598
- @param {any} value
18743
+ @param {any} [value]
18599
18744
  The dismissal value.
18600
- @param {Object} options
18745
+ @param {Object} [options]
18601
18746
  See options for `up.layer.dismiss()`.
18602
18747
  @stable
18603
18748
  */
@@ -18663,7 +18808,7 @@ You can define custom animations using `up.transition()` and
18663
18808
  */
18664
18809
 
18665
18810
  /***
18666
- Listens to a ([DOM event](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Events)
18811
+ Listens to a [DOM event](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Events)
18667
18812
  that originated on an element [contained](/up.Layer.prototype.contains) by the [current layer](/up.layer.current).
18668
18813
 
18669
18814
  This is a shortcut for `up.layer.current.on()`.
@@ -18844,6 +18989,11 @@ With these [`up-target`](/a-up-follow#up-target) annotations Unpoly only updates
18844
18989
  The JavaScript environment will persist and the user will not see a white flash while the
18845
18990
  new page is loading.
18846
18991
 
18992
+ @see a[up-follow]
18993
+ @see a[up-instant]
18994
+ @see a[up-preload]
18995
+ @see up.follow
18996
+
18847
18997
  @module up.link
18848
18998
  */
18849
18999
 
@@ -19015,8 +19165,7 @@ new page is loading.
19015
19165
  };
19016
19166
 
19017
19167
  /***
19018
- Fetches the given link's `[href]` with JavaScript and [replaces](/up.replace) the
19019
- [current layer](/up.layer.current) with HTML from the response.
19168
+ Follows the given link with JavaScript and updates a fragment with the server response.
19020
19169
 
19021
19170
  By default the layer's [main element](/main)
19022
19171
  will be replaced. Attributes like `a[up-target]`
@@ -19160,7 +19309,20 @@ new page is loading.
19160
19309
 
19161
19310
  The event is emitted on the `<a>` element that is being followed.
19162
19311
 
19163
- TODO: Document that listeners may manipulate options
19312
+ \#\#\# Changing render options
19313
+
19314
+ Listeners may inspect and manipulate [render options](/up.render) for the coming fragment update.
19315
+
19316
+ The code below will open all form-contained links in an overlay, as to not
19317
+ lose the user's form data:
19318
+
19319
+ ```js
19320
+ up.on('up:link:follow', function(event, link) {
19321
+ if (link.closest('form')) {
19322
+ event.renderOptions.layer = 'new'
19323
+ }
19324
+ })
19325
+ ```
19164
19326
 
19165
19327
  @event up:link:follow
19166
19328
  @param {Element} event.target
@@ -19464,8 +19626,7 @@ new page is loading.
19464
19626
  };
19465
19627
 
19466
19628
  /***
19467
- [Follows](/up.follow) this link with JavaScript and replaces a CSS selector
19468
- on the current page with a corresponding element from the response.
19629
+ [Follows](/up.follow) this link with JavaScript and updates a fragment with the server response.
19469
19630
 
19470
19631
  Following a link is considered [navigation](/navigation) by default.
19471
19632
 
@@ -19601,7 +19762,7 @@ new page is loading.
19601
19762
  If set to `false`, the history will remain unchanged.
19602
19763
 
19603
19764
  [Overlays](/up.layer) will only change the browser URL and window title if the overlay
19604
- has [visible history](/up.layer.historyVisible), even with `{ history: true }`.
19765
+ has [visible history](/up.layer.historyVisible), even when `[up-history=true]` is set.
19605
19766
 
19606
19767
  @param [up-title]
19607
19768
  An explicit document title to use after rendering.
@@ -19731,12 +19892,7 @@ new page is loading.
19731
19892
  });
19732
19893
 
19733
19894
  /***
19734
- TODO: Explain that this generates an up:click event, works on any elements, can can be used to accelerate links
19735
-
19736
- By adding an `up-instant` attribute to a link, the destination will be
19737
- fetched on `mousedown` instead of `click` (`mouseup`).
19738
-
19739
- <a href="/users" up-follow up-instant>User list</a>
19895
+ Follows this link on `mousedown` instead of `click`.
19740
19896
 
19741
19897
  This will save precious milliseconds that otherwise spent
19742
19898
  on waiting for the user to release the mouse button. Since an
@@ -19748,6 +19904,10 @@ new page is loading.
19748
19904
  navigation actions this isn't needed. E.g. popular operation
19749
19905
  systems switch tabs on `mousedown` instead of `click`.
19750
19906
 
19907
+ \#\#\# Example
19908
+
19909
+ <a href="/users" up-follow up-instant>User list</a>
19910
+
19751
19911
  \#\#\# Accessibility
19752
19912
 
19753
19913
  If the user activates an element using their keyboard, the `up:click` event will be emitted
@@ -19846,11 +20006,9 @@ new page is loading.
19846
20006
  });
19847
20007
 
19848
20008
  /***
19849
- Links with an `up-preload` attribute will silently fetch their target
19850
- when the user hovers over the click area, or when the user puts her
19851
- mouse/finger down (before releasing).
20009
+ Preloads this link when the user hovers over it.
19852
20010
 
19853
- When the link is clicked later, the response will already be cached,
20011
+ When the link is clicked later the response will already be cached,
19854
20012
  making the interaction feel instant.
19855
20013
 
19856
20014
  @selector a[up-preload]
@@ -19893,9 +20051,12 @@ new page is loading.
19893
20051
  Forms
19894
20052
  =====
19895
20053
 
19896
- Unpoly comes with functionality to [submit](/form-up-submit) and [validate](/input-up-validate)
19897
- forms without leaving the current page. This means you can replace page fragments,
19898
- open dialogs with sub-forms, etc. all without losing form state.
20054
+ The `up.form` module helps you work with non-trivial forms.
20055
+
20056
+ @see form[up-submit]
20057
+ @see form[up-validate]
20058
+ @see input[up-switch]
20059
+ @see form[up-autosubmit]
19899
20060
 
19900
20061
  @module up.form
19901
20062
  */
@@ -20142,7 +20303,6 @@ open dialogs with sub-forms, etc. all without losing form state.
20142
20303
  The `<form>` element that will be submitted.
20143
20304
  @param {Object} event.renderOptions
20144
20305
  An object with [render options](/up.render) for the fragment update
20145
- that will show the validation results.
20146
20306
 
20147
20307
  Listeners may inspect and modify these options.
20148
20308
  @param event.preventDefault()
@@ -20453,18 +20613,21 @@ open dialogs with sub-forms, etc. all without losing form state.
20453
20613
  };
20454
20614
 
20455
20615
  /***
20456
- Forms with an `up-target` attribute are [submitted via AJAX](/up.submit)
20457
- instead of triggering a full page reload.
20458
-
20459
- <form method="post" action="/users" up-target=".main">
20460
- ...
20461
- </form>
20616
+ Submits this form via JavaScript and updates a fragment with the server response.
20462
20617
 
20463
20618
  The server response is searched for the selector given in `up-target`.
20464
20619
  The selector content is then [replaced](/up.replace) in the current page.
20465
20620
 
20466
20621
  The programmatic variant of this is the [`up.submit()`](/up.submit) function.
20467
20622
 
20623
+ \#\#\# Example
20624
+
20625
+ ```html
20626
+ <form method="post" action="/users" up-submit>
20627
+ ...
20628
+ </form>
20629
+ ```
20630
+
20468
20631
  \#\#\# Failed submission
20469
20632
 
20470
20633
  When the server was unable to save the form due to invalid params,
@@ -20684,11 +20847,13 @@ open dialogs with sub-forms, etc. all without losing form state.
20684
20847
  */
20685
20848
 
20686
20849
  /***
20687
- Performs [server-side validation](/input-up-validate) when any fieldset within this form changes.
20850
+ Validates this form on the server when any field changes and shows validation errors.
20688
20851
 
20689
20852
  You can configure what Unpoly considers a fieldset by adding CSS selectors to the
20690
20853
  `up.form.config.validateTargets` array.
20691
20854
 
20855
+ See `input[up-validate]` for detailed documentation.
20856
+
20692
20857
  @selector form[up-validate]
20693
20858
  @param up-validate
20694
20859
  The CSS selector to update with the server response.
@@ -20705,7 +20870,7 @@ open dialogs with sub-forms, etc. all without losing form state.
20705
20870
  });
20706
20871
 
20707
20872
  /***
20708
- Show or hide elements when a `<select>` or `<input>` has a given value.
20873
+ Show or hide elements when a form field is set to a given value.
20709
20874
 
20710
20875
  \#\#\# Example: Select options
20711
20876
 
@@ -20943,7 +21108,7 @@ open dialogs with sub-forms, etc. all without losing form state.
20943
21108
  */
20944
21109
 
20945
21110
  /***
20946
- Submits the form when *any* field changes.
21111
+ Submits the form when any field changes.
20947
21112
 
20948
21113
  Both the form and the field will be assigned a CSS class [`up-active`](/form-up-active)
20949
21114
  while the autosubmitted form is loading.
@@ -21035,6 +21200,9 @@ Once the response is received the URL will change to `/bar` and the `up-active`
21035
21200
  <a href="/bar" up-follow class="up-current">Bar</a>
21036
21201
  </nav>
21037
21202
 
21203
+ @see [up-nav]
21204
+ @see a.up-current
21205
+ @see a.up-active
21038
21206
 
21039
21207
  @module up.feedback
21040
21208
  */
@@ -21409,8 +21577,10 @@ Once the response is received the URL will change to `/bar` and the `up-active`
21409
21577
  Passive updates
21410
21578
  ===============
21411
21579
 
21412
- This work-in-progress package will contain functionality to
21413
- passively receive updates from the server.
21580
+ This package contains functionality to passively receive updates from the server.
21581
+
21582
+ @see [up-hungry]
21583
+ @see [up-poll]
21414
21584
 
21415
21585
  @module up.radio
21416
21586
  */
@@ -21425,13 +21595,16 @@ passively receive updates from the server.
21425
21595
  Configures defaults for passive updates.
21426
21596
 
21427
21597
  @property up.radio.config
21598
+
21428
21599
  @param {Array<string>} [config.hungrySelectors]
21429
21600
  An array of CSS selectors that is replaced whenever a matching element is found in a response.
21430
21601
  These elements are replaced even when they were not targeted directly.
21431
21602
 
21432
21603
  By default this contains the [`[up-hungry]`](/up-hungry) attribute.
21604
+
21433
21605
  @param {number} [config.pollInterval=30000]
21434
21606
  The default [polling](/up-poll] interval in milliseconds.
21607
+
21435
21608
  @param {boolean|string|Function(Element)} [config.pollEnabled=true]
21436
21609
  Whether Unpoly will follow instructions to poll fragments, like the `[up-poll]` attribute.
21437
21610
 
@@ -21446,6 +21619,7 @@ passively receive updates from the server.
21446
21619
  When set to `false`, Unpoly will never allow polling.
21447
21620
 
21448
21621
  You may also pass a function that accepts the polling fragment and returns `true`, `false` or `'auto'`.
21622
+
21449
21623
  @stable
21450
21624
  */
21451
21625
  config = new up.Config(function() {
@@ -21468,9 +21642,8 @@ passively receive updates from the server.
21468
21642
  };
21469
21643
 
21470
21644
  /***
21471
- Elements with an `[up-hungry]` attribute are [updated](/up.replace) whenever there is a
21472
- matching element found in a successful response. The element is replaced even
21473
- when it isn't targeted directly.
21645
+ Elements with an `[up-hungry]` attribute are updated whenever the server
21646
+ sends a matching element, even if the element isn't targeted.
21474
21647
 
21475
21648
  Use cases for this are unread message counters or notification flashes.
21476
21649
  Such elements often live in the layout, outside of the content area that is
@@ -21562,21 +21735,27 @@ passively receive updates from the server.
21562
21735
  Assume an application layout with an unread message counter.
21563
21736
  You can use `[up-poll]` to refresh the counter every 30 seconds:
21564
21737
 
21565
- <div class="unread-count" up-poll>
21566
- 2 new messages
21567
- </div>
21738
+ ```html
21739
+ <div class="unread-count" up-poll>
21740
+ 2 new messages
21741
+ </div>
21742
+ ```
21568
21743
 
21569
21744
  \#\#\# Controlling the reload interval
21570
21745
 
21571
21746
  You may set an optional `[up-interval]` attribute to set the reload interval in milliseconds:
21572
21747
 
21573
- <div class="unread-count" up-poll up-interval="10000">
21574
- 2 new messages
21575
- </div>
21748
+ ```html
21749
+ <div class="unread-count" up-poll up-interval="10000">
21750
+ 2 new messages
21751
+ </div>
21752
+ ```
21576
21753
 
21577
21754
  If the value is omitted, a global default is used. You may configure the default like this:
21578
21755
 
21579
- up.radio.config.pollInterval = 10000
21756
+ ```js
21757
+ up.radio.config.pollInterval = 10000
21758
+ ```
21580
21759
 
21581
21760
  \#\#\# Controlling the source URL
21582
21761
 
@@ -21584,13 +21763,20 @@ passively receive updates from the server.
21584
21763
 
21585
21764
  To reload from another URL, set an `[up-source]` attribute on the polling element:
21586
21765
 
21587
- <div class="unread-count" up-poll up-source="/unread-count">
21588
- 2 new messages
21589
- </div>
21766
+ ```html
21767
+ <div class="unread-count" up-poll up-source="/unread-count">
21768
+ 2 new messages
21769
+ </div>
21770
+ ```
21590
21771
 
21591
21772
  \#\#\# Skipping updates when nothing changed
21592
21773
 
21593
- TODO: Document [up-time] and X-Up-Reload-From-Time (currently both documented in `X-Up-Reload-From-Time`).
21774
+ When polling a fragment periodically we want to avoid rendering unchanged content.
21775
+ This saves <b>CPU time</b> and reduces the <b>bandwidth cost</b> for a
21776
+ request/response exchange to **~1 KB**.
21777
+
21778
+ To achieve this we timestamp your fragments with an `[up-time]` attribute to indicate
21779
+ when the underlying data was last changed. See `[up-time]` for a detailed example.
21594
21780
 
21595
21781
  @selector [up-poll]
21596
21782
  @param [up-interval]