@pageboard/html 0.14.39 → 0.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/elements/form.js +60 -4
- package/elements/input-property.js +1 -1
- package/elements/link.js +3 -3
- package/elements/menu.js +1 -1
- package/lib/formdata.js +21 -0
- package/lib/object-fit-images.js +243 -0
- package/lib/stickyfill.js +546 -0
- package/package.json +2 -2
- package/ui/image.js +61 -62
- package/ui/input-file.js +5 -4
- package/ui/layout.js +18 -51
- package/ui/pagination.js +1 -1
package/elements/form.js
CHANGED
|
@@ -38,7 +38,7 @@ exports.query_form = {
|
|
|
38
38
|
title: 'Page',
|
|
39
39
|
nullable: true,
|
|
40
40
|
type: "string",
|
|
41
|
-
format: "
|
|
41
|
+
format: "page",
|
|
42
42
|
$helper: "page"
|
|
43
43
|
},
|
|
44
44
|
parameters: {
|
|
@@ -79,7 +79,7 @@ exports.api_form = {
|
|
|
79
79
|
properties: {
|
|
80
80
|
name: {
|
|
81
81
|
title: 'Name',
|
|
82
|
-
description: "Used by query 'submit' or 'toggle'\nExposes
|
|
82
|
+
description: "Used by query 'submit' or 'toggle'\nExposes /@api/form/$name",
|
|
83
83
|
type: 'string',
|
|
84
84
|
format: 'id',
|
|
85
85
|
nullable: true
|
|
@@ -101,15 +101,71 @@ exports.api_form = {
|
|
|
101
101
|
description: 'Choose a service',
|
|
102
102
|
$ref: '/writes'
|
|
103
103
|
},
|
|
104
|
+
request: {
|
|
105
|
+
title: 'Map inputs',
|
|
106
|
+
description: `
|
|
107
|
+
expr is supposed to be used to merge stuff into html,
|
|
108
|
+
not really to merge stuff into methods parameters
|
|
109
|
+
Also expr has a bad design because
|
|
110
|
+
- it can be replaced by a binding element inside the block
|
|
111
|
+
- it forces the expression to be in a specific attribute,
|
|
112
|
+
and mostly when a block has no content (so a binding cannot be used)
|
|
113
|
+
- the editor is ugly and shows fields that might not even be merged into html
|
|
114
|
+
Use cases
|
|
115
|
+
- links in anchors, images
|
|
116
|
+
- input or buttons values, checked attributes
|
|
117
|
+
- hidden attributes
|
|
118
|
+
- show/hide blocks depending on response
|
|
119
|
+
The "expr" mecanism could instead be a list of expressions like
|
|
120
|
+
[url|as:url|assign:.query.reservation:$query.reservation]
|
|
121
|
+
[url][$query|pick:text:cover|as:query]
|
|
122
|
+
|
|
123
|
+
Things to solve:
|
|
124
|
+
- do we want expr to be able to do changes outside the DOM of the block itself ? (no, this should be done by a binding element)
|
|
125
|
+
- do we want expr to change only data before merge - outside of any dom context ? Possibly ! In which case the current system is not that bad,
|
|
126
|
+
but it should not use matchdom dom plugin at all
|
|
127
|
+
- how to deal with "template" expressions when one cannot insert a binding
|
|
128
|
+
element ? Is it really something that happens ?
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
`,
|
|
133
|
+
type: 'object',
|
|
134
|
+
nullable: true
|
|
135
|
+
},
|
|
136
|
+
response: {
|
|
137
|
+
title: 'Map outputs',
|
|
138
|
+
description: `
|
|
139
|
+
'item.id': '[item.data.id]'
|
|
140
|
+
'item.title': '[item.content.title]'
|
|
141
|
+
// etc...
|
|
142
|
+
`,
|
|
143
|
+
type: 'object',
|
|
144
|
+
nullable: true
|
|
145
|
+
},
|
|
104
146
|
redirection: {
|
|
105
147
|
title: 'Success',
|
|
148
|
+
description: `
|
|
149
|
+
redirection can be used by client,
|
|
150
|
+
to change the page state. In which case the "url" is not an api url.
|
|
151
|
+
It can be used by the server, in which case the "url" is an api url.
|
|
152
|
+
The parameters for a page url make the query, and $query, $request, $response are available.
|
|
153
|
+
The parameters for a user api call are...?
|
|
154
|
+
The user api endpoint is a real url (/@api/xxx) that can expect
|
|
155
|
+
a body ($request) and a query ($query) too.
|
|
156
|
+
Currently client pages use a trick to redirect and submit: a specific parameter triggers a form submit on the redirected page. This makes sense in the context of page navigation - the body is filled by the form that is triggered by the parameters.
|
|
157
|
+
How can that be transposed for internal user api redirection ?
|
|
158
|
+
1. since it redirects, output mapping can be done to format the $response
|
|
159
|
+
2. in the next api call, parameters mean $query, $response becomes $request ?
|
|
160
|
+
3. this works if output can merge $query, $request as well
|
|
161
|
+
`,
|
|
106
162
|
type: 'object',
|
|
107
163
|
properties: {
|
|
108
164
|
url: {
|
|
109
165
|
title: 'Page',
|
|
110
166
|
nullable: true,
|
|
111
167
|
type: "string",
|
|
112
|
-
format: "
|
|
168
|
+
format: "page",
|
|
113
169
|
$helper: "page"
|
|
114
170
|
},
|
|
115
171
|
parameters: {
|
|
@@ -160,7 +216,7 @@ exports.api_form = {
|
|
|
160
216
|
contents: 'block+',
|
|
161
217
|
tag: 'form[method="post"]',
|
|
162
218
|
html: `<form is="element-form" method="post" name="[name]" masked="[masked]"
|
|
163
|
-
action="
|
|
219
|
+
action="/@api/form/[name|else:$id]"
|
|
164
220
|
parameters="[$expr?.action?.parameters|as:expressions]"
|
|
165
221
|
success="[redirection.url][redirection.parameters|as:query]"
|
|
166
222
|
badrequest="[badrequest.url][badrequest.parameters|as:query]"
|
package/elements/link.js
CHANGED
|
@@ -29,7 +29,7 @@ exports.link = {
|
|
|
29
29
|
nullable: true,
|
|
30
30
|
$helper: {
|
|
31
31
|
name: 'datalist',
|
|
32
|
-
url: '
|
|
32
|
+
url: '/@api/languages'
|
|
33
33
|
}
|
|
34
34
|
},
|
|
35
35
|
id: {
|
|
@@ -75,7 +75,7 @@ exports.link_button = {
|
|
|
75
75
|
nullable: true,
|
|
76
76
|
$helper: {
|
|
77
77
|
name: 'datalist',
|
|
78
|
-
url: '
|
|
78
|
+
url: '/@api/languages'
|
|
79
79
|
}
|
|
80
80
|
},
|
|
81
81
|
full: {
|
|
@@ -108,7 +108,7 @@ exports.link_button = {
|
|
|
108
108
|
default: null
|
|
109
109
|
}
|
|
110
110
|
},
|
|
111
|
-
contents: "
|
|
111
|
+
contents: "inline*",
|
|
112
112
|
group: "block",
|
|
113
113
|
html: '<a href="[url|lang:[lang]]" hreflang="[lang]" class="ui [full|alt:fluid:] [icon] [compact] [float|post:%20floated] button"></a>',
|
|
114
114
|
stylesheets: [
|
package/elements/menu.js
CHANGED
package/lib/formdata.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/*! formdata-polyfill. MIT License. Jimmy W?rting <https://jimmy.warting.se/opensource> */
|
|
2
|
+
;(function(){var h;function l(a){var b=0;return function(){return b<a.length?{done:!1,value:a[b++]}:{done:!0}}}var m="function"==typeof Object.defineProperties?Object.defineProperty:function(a,b,c){if(a==Array.prototype||a==Object.prototype)return a;a[b]=c.value;return a};
|
|
3
|
+
function n(a){a=["object"==typeof globalThis&&globalThis,a,"object"==typeof window&&window,"object"==typeof self&&self,"object"==typeof global&&global];for(var b=0;b<a.length;++b){var c=a[b];if(c&&c.Math==Math)return c}throw Error("Cannot find global object");}var q=n(this);function r(a,b){if(b)a:{var c=q;a=a.split(".");for(var d=0;d<a.length-1;d++){var e=a[d];if(!(e in c))break a;c=c[e]}a=a[a.length-1];d=c[a];b=b(d);b!=d&&null!=b&&m(c,a,{configurable:!0,writable:!0,value:b})}}
|
|
4
|
+
r("Symbol",function(a){function b(f){if(this instanceof b)throw new TypeError("Symbol is not a constructor");return new c(d+(f||"")+"_"+e++,f)}function c(f,g){this.A=f;m(this,"description",{configurable:!0,writable:!0,value:g})}if(a)return a;c.prototype.toString=function(){return this.A};var d="jscomp_symbol_"+(1E9*Math.random()>>>0)+"_",e=0;return b});
|
|
5
|
+
r("Symbol.iterator",function(a){if(a)return a;a=Symbol("Symbol.iterator");for(var b="Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array".split(" "),c=0;c<b.length;c++){var d=q[b[c]];"function"===typeof d&&"function"!=typeof d.prototype[a]&&m(d.prototype,a,{configurable:!0,writable:!0,value:function(){return u(l(this))}})}return a});function u(a){a={next:a};a[Symbol.iterator]=function(){return this};return a}
|
|
6
|
+
function v(a){var b="undefined"!=typeof Symbol&&Symbol.iterator&&a[Symbol.iterator];return b?b.call(a):{next:l(a)}}var w;if("function"==typeof Object.setPrototypeOf)w=Object.setPrototypeOf;else{var y;a:{var z={a:!0},A={};try{A.__proto__=z;y=A.a;break a}catch(a){}y=!1}w=y?function(a,b){a.__proto__=b;if(a.__proto__!==b)throw new TypeError(a+" is not extensible");return a}:null}var B=w;function C(){this.m=!1;this.j=null;this.v=void 0;this.h=1;this.u=this.C=0;this.l=null}
|
|
7
|
+
function D(a){if(a.m)throw new TypeError("Generator is already running");a.m=!0}C.prototype.o=function(a){this.v=a};C.prototype.s=function(a){this.l={D:a,F:!0};this.h=this.C||this.u};C.prototype.return=function(a){this.l={return:a};this.h=this.u};function E(a,b){a.h=3;return{value:b}}function F(a){this.g=new C;this.G=a}F.prototype.o=function(a){D(this.g);if(this.g.j)return G(this,this.g.j.next,a,this.g.o);this.g.o(a);return H(this)};
|
|
8
|
+
function I(a,b){D(a.g);var c=a.g.j;if(c)return G(a,"return"in c?c["return"]:function(d){return{value:d,done:!0}},b,a.g.return);a.g.return(b);return H(a)}F.prototype.s=function(a){D(this.g);if(this.g.j)return G(this,this.g.j["throw"],a,this.g.o);this.g.s(a);return H(this)};
|
|
9
|
+
function G(a,b,c,d){try{var e=b.call(a.g.j,c);if(!(e instanceof Object))throw new TypeError("Iterator result "+e+" is not an object");if(!e.done)return a.g.m=!1,e;var f=e.value}catch(g){return a.g.j=null,a.g.s(g),H(a)}a.g.j=null;d.call(a.g,f);return H(a)}function H(a){for(;a.g.h;)try{var b=a.G(a.g);if(b)return a.g.m=!1,{value:b.value,done:!1}}catch(c){a.g.v=void 0,a.g.s(c)}a.g.m=!1;if(a.g.l){b=a.g.l;a.g.l=null;if(b.F)throw b.D;return{value:b.return,done:!0}}return{value:void 0,done:!0}}
|
|
10
|
+
function J(a){this.next=function(b){return a.o(b)};this.throw=function(b){return a.s(b)};this.return=function(b){return I(a,b)};this[Symbol.iterator]=function(){return this}}function K(a,b){b=new J(new F(b));B&&a.prototype&&B(b,a.prototype);return b}function L(a,b){a instanceof String&&(a+="");var c=0,d=!1,e={next:function(){if(!d&&c<a.length){var f=c++;return{value:b(f,a[f]),done:!1}}d=!0;return{done:!0,value:void 0}}};e[Symbol.iterator]=function(){return e};return e}
|
|
11
|
+
r("Array.prototype.entries",function(a){return a?a:function(){return L(this,function(b,c){return[b,c]})}});
|
|
12
|
+
if("undefined"!==typeof Blob&&("undefined"===typeof FormData||!FormData.prototype.keys)){var M=function(a,b){for(var c=0;c<a.length;c++)b(a[c])},N=function(a){return a.replace(/\r?\n|\r/g,"\r\n")},O=function(a,b,c){if(b instanceof Blob){c=void 0!==c?String(c+""):"string"===typeof b.name?b.name:"blob";if(b.name!==c||"[object Blob]"===Object.prototype.toString.call(b))b=new File([b],c);return[String(a),b]}return[String(a),String(b)]},P=function(a,b){if(a.length<b)throw new TypeError(b+" argument required, but only "+
|
|
13
|
+
a.length+" present.");},Q="object"===typeof globalThis?globalThis:"object"===typeof window?window:"object"===typeof self?self:this,R=Q.FormData,S=Q.XMLHttpRequest&&Q.XMLHttpRequest.prototype.send,T=Q.Request&&Q.fetch,U=Q.navigator&&Q.navigator.sendBeacon,V=Q.Element&&Q.Element.prototype,W=Q.Symbol&&Symbol.toStringTag;W&&(Blob.prototype[W]||(Blob.prototype[W]="Blob"),"File"in Q&&!File.prototype[W]&&(File.prototype[W]="File"));try{new File([],"")}catch(a){Q.File=function(b,c,d){b=new Blob(b,d||{});
|
|
14
|
+
Object.defineProperties(b,{name:{value:c},lastModified:{value:+(d&&void 0!==d.lastModified?new Date(d.lastModified):new Date)},toString:{value:function(){return"[object File]"}}});W&&Object.defineProperty(b,W,{value:"File"});return b}}var escape=function(a){return a.replace(/\n/g,"%0A").replace(/\r/g,"%0D").replace(/"/g,"%22")},X=function(a){this.i=[];var b=this;a&&M(a.elements,function(c){if(c.name&&!c.disabled&&"submit"!==c.type&&"button"!==c.type&&!c.matches("form fieldset[disabled] *"))if("file"===
|
|
15
|
+
c.type){var d=c.files&&c.files.length?c.files:[new File([],"",{type:"application/octet-stream"})];M(d,function(e){b.append(c.name,e)})}else"select-multiple"===c.type||"select-one"===c.type?M(c.options,function(e){!e.disabled&&e.selected&&b.append(c.name,e.value)}):"checkbox"===c.type||"radio"===c.type?c.checked&&b.append(c.name,c.value):(d="textarea"===c.type?N(c.value):c.value,b.append(c.name,d))})};h=X.prototype;h.append=function(a,b,c){P(arguments,2);this.i.push(O(a,b,c))};h.delete=function(a){P(arguments,
|
|
16
|
+
1);var b=[];a=String(a);M(this.i,function(c){c[0]!==a&&b.push(c)});this.i=b};h.entries=function b(){var c,d=this;return K(b,function(e){1==e.h&&(c=0);if(3!=e.h)return c<d.i.length?e=E(e,d.i[c]):(e.h=0,e=void 0),e;c++;e.h=2})};h.forEach=function(b,c){P(arguments,1);for(var d=v(this),e=d.next();!e.done;e=d.next()){var f=v(e.value);e=f.next().value;f=f.next().value;b.call(c,f,e,this)}};h.get=function(b){P(arguments,1);var c=this.i;b=String(b);for(var d=0;d<c.length;d++)if(c[d][0]===b)return c[d][1];
|
|
17
|
+
return null};h.getAll=function(b){P(arguments,1);var c=[];b=String(b);M(this.i,function(d){d[0]===b&&c.push(d[1])});return c};h.has=function(b){P(arguments,1);b=String(b);for(var c=0;c<this.i.length;c++)if(this.i[c][0]===b)return!0;return!1};h.keys=function c(){var d=this,e,f,g,k,p;return K(c,function(t){1==t.h&&(e=v(d),f=e.next());if(3!=t.h){if(f.done){t.h=0;return}g=f.value;k=v(g);p=k.next().value;return E(t,p)}f=e.next();t.h=2})};h.set=function(c,d,e){P(arguments,2);c=String(c);var f=[],g=O(c,
|
|
18
|
+
d,e),k=!0;M(this.i,function(p){p[0]===c?k&&(k=!f.push(g)):f.push(p)});k&&f.push(g);this.i=f};h.values=function d(){var e=this,f,g,k,p,t;return K(d,function(x){1==x.h&&(f=v(e),g=f.next());if(3!=x.h){if(g.done){x.h=0;return}k=g.value;p=v(k);p.next();t=p.next().value;return E(x,t)}g=f.next();x.h=2})};X.prototype._asNative=function(){for(var d=new R,e=v(this),f=e.next();!f.done;f=e.next()){var g=v(f.value);f=g.next().value;g=g.next().value;d.append(f,g)}return d};X.prototype._blob=function(){var d="----formdata-polyfill-"+
|
|
19
|
+
Math.random(),e=[],f="--"+d+'\r\nContent-Disposition: form-data; name="';this.forEach(function(g,k){return"string"==typeof g?e.push(f+escape(N(k))+('"\r\n\r\n'+N(g)+"\r\n")):e.push(f+escape(N(k))+('"; filename="'+escape(g.name)+'"\r\nContent-Type: '+(g.type||"application/octet-stream")+"\r\n\r\n"),g,"\r\n")});e.push("--"+d+"--");return new Blob(e,{type:"multipart/form-data; boundary="+d})};X.prototype[Symbol.iterator]=function(){return this.entries()};X.prototype.toString=function(){return"[object FormData]"};
|
|
20
|
+
V&&!V.matches&&(V.matches=V.matchesSelector||V.mozMatchesSelector||V.msMatchesSelector||V.oMatchesSelector||V.webkitMatchesSelector||function(d){d=(this.document||this.ownerDocument).querySelectorAll(d);for(var e=d.length;0<=--e&&d.item(e)!==this;);return-1<e});W&&(X.prototype[W]="FormData");if(S){var Y=Q.XMLHttpRequest.prototype.setRequestHeader;Q.XMLHttpRequest.prototype.setRequestHeader=function(d,e){Y.call(this,d,e);"content-type"===d.toLowerCase()&&(this.B=!0)};Q.XMLHttpRequest.prototype.send=
|
|
21
|
+
function(d){d instanceof X?(d=d._blob(),this.B||this.setRequestHeader("Content-Type",d.type),S.call(this,d)):S.call(this,d)}}T&&(Q.fetch=function(d,e){e&&e.body&&e.body instanceof X&&(e.body=e.body._blob());return T.call(this,d,e)});U&&(Q.navigator.sendBeacon=function(d,e){e instanceof X&&(e=e._asNative());return U.call(this,d,e)});Q.FormData=X};})();
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
var objectFitImages = (function () {
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
function getDefaultExportFromCjs (x) {
|
|
5
|
+
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/*! npm.im/object-fit-images 3.2.4 */
|
|
9
|
+
|
|
10
|
+
var OFI = 'bfred-it:object-fit-images';
|
|
11
|
+
var propRegex = /(object-fit|object-position)\s*:\s*([-.\w\s%]+)/g;
|
|
12
|
+
var testImg = typeof Image === 'undefined' ? {style: {'object-position': 1}} : new Image();
|
|
13
|
+
var supportsObjectFit = 'object-fit' in testImg.style;
|
|
14
|
+
var supportsObjectPosition = 'object-position' in testImg.style;
|
|
15
|
+
var supportsOFI = 'background-size' in testImg.style;
|
|
16
|
+
var supportsCurrentSrc = typeof testImg.currentSrc === 'string';
|
|
17
|
+
var nativeGetAttribute = testImg.getAttribute;
|
|
18
|
+
var nativeSetAttribute = testImg.setAttribute;
|
|
19
|
+
var autoModeEnabled = false;
|
|
20
|
+
|
|
21
|
+
function createPlaceholder(w, h) {
|
|
22
|
+
return ("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='" + w + "' height='" + h + "'%3E%3C/svg%3E");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function polyfillCurrentSrc(el) {
|
|
26
|
+
if (el.srcset && !supportsCurrentSrc && window.picturefill) {
|
|
27
|
+
var pf = window.picturefill._;
|
|
28
|
+
// parse srcset with picturefill where currentSrc isn't available
|
|
29
|
+
if (!el[pf.ns] || !el[pf.ns].evaled) {
|
|
30
|
+
// force synchronous srcset parsing
|
|
31
|
+
pf.fillImg(el, {reselect: true});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (!el[pf.ns].curSrc) {
|
|
35
|
+
// force picturefill to parse srcset
|
|
36
|
+
el[pf.ns].supported = false;
|
|
37
|
+
pf.fillImg(el, {reselect: true});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// retrieve parsed currentSrc, if any
|
|
41
|
+
el.currentSrc = el[pf.ns].curSrc || el.src;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function getStyle(el) {
|
|
46
|
+
var style = getComputedStyle(el).fontFamily;
|
|
47
|
+
var parsed;
|
|
48
|
+
var props = {};
|
|
49
|
+
while ((parsed = propRegex.exec(style)) !== null) {
|
|
50
|
+
props[parsed[1]] = parsed[2];
|
|
51
|
+
}
|
|
52
|
+
return props;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function setPlaceholder(img, width, height) {
|
|
56
|
+
// Default: fill width, no height
|
|
57
|
+
var placeholder = createPlaceholder(width || 1, height || 0);
|
|
58
|
+
|
|
59
|
+
// Only set placeholder if it's different
|
|
60
|
+
if (nativeGetAttribute.call(img, 'src') !== placeholder) {
|
|
61
|
+
nativeSetAttribute.call(img, 'src', placeholder);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function onImageReady(img, callback) {
|
|
66
|
+
// naturalWidth is only available when the image headers are loaded,
|
|
67
|
+
// this loop will poll it every 100ms.
|
|
68
|
+
if (img.naturalWidth) {
|
|
69
|
+
callback(img);
|
|
70
|
+
} else {
|
|
71
|
+
setTimeout(onImageReady, 100, img, callback);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function fixOne(el) {
|
|
76
|
+
var style = getStyle(el);
|
|
77
|
+
var ofi = el[OFI];
|
|
78
|
+
style['object-fit'] = style['object-fit'] || 'fill'; // default value
|
|
79
|
+
|
|
80
|
+
// Avoid running where unnecessary, unless OFI had already done its deed
|
|
81
|
+
if (!ofi.img) {
|
|
82
|
+
// fill is the default behavior so no action is necessary
|
|
83
|
+
if (style['object-fit'] === 'fill') {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Where object-fit is supported and object-position isn't (Safari < 10)
|
|
88
|
+
if (
|
|
89
|
+
!ofi.skipTest && // unless user wants to apply regardless of browser support
|
|
90
|
+
supportsObjectFit && // if browser already supports object-fit
|
|
91
|
+
!style['object-position'] // unless object-position is used
|
|
92
|
+
) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// keep a clone in memory while resetting the original to a blank
|
|
98
|
+
if (!ofi.img) {
|
|
99
|
+
ofi.img = new Image(el.width, el.height);
|
|
100
|
+
ofi.img.srcset = nativeGetAttribute.call(el, "data-ofi-srcset") || el.srcset;
|
|
101
|
+
ofi.img.src = nativeGetAttribute.call(el, "data-ofi-src") || el.src;
|
|
102
|
+
|
|
103
|
+
// preserve for any future cloneNode calls
|
|
104
|
+
// https://github.com/bfred-it/object-fit-images/issues/53
|
|
105
|
+
nativeSetAttribute.call(el, "data-ofi-src", el.src);
|
|
106
|
+
if (el.srcset) {
|
|
107
|
+
nativeSetAttribute.call(el, "data-ofi-srcset", el.srcset);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
setPlaceholder(el, el.naturalWidth || el.width, el.naturalHeight || el.height);
|
|
111
|
+
|
|
112
|
+
// remove srcset because it overrides src
|
|
113
|
+
if (el.srcset) {
|
|
114
|
+
el.srcset = '';
|
|
115
|
+
}
|
|
116
|
+
try {
|
|
117
|
+
keepSrcUsable(el);
|
|
118
|
+
} catch (err) {
|
|
119
|
+
if (window.console) {
|
|
120
|
+
console.warn('https://bit.ly/ofi-old-browser');
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
polyfillCurrentSrc(ofi.img);
|
|
126
|
+
|
|
127
|
+
el.style.backgroundImage = "url(\"" + ((ofi.img.currentSrc || ofi.img.src).replace(/"/g, '\\"')) + "\")";
|
|
128
|
+
el.style.backgroundPosition = style['object-position'] || 'center';
|
|
129
|
+
el.style.backgroundRepeat = 'no-repeat';
|
|
130
|
+
el.style.backgroundOrigin = 'content-box';
|
|
131
|
+
|
|
132
|
+
if (/scale-down/.test(style['object-fit'])) {
|
|
133
|
+
onImageReady(ofi.img, function () {
|
|
134
|
+
if (ofi.img.naturalWidth > el.width || ofi.img.naturalHeight > el.height) {
|
|
135
|
+
el.style.backgroundSize = 'contain';
|
|
136
|
+
} else {
|
|
137
|
+
el.style.backgroundSize = 'auto';
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
} else {
|
|
141
|
+
el.style.backgroundSize = style['object-fit'].replace('none', 'auto').replace('fill', '100% 100%');
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
onImageReady(ofi.img, function (img) {
|
|
145
|
+
setPlaceholder(el, img.naturalWidth, img.naturalHeight);
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function keepSrcUsable(el) {
|
|
150
|
+
var descriptors = {
|
|
151
|
+
get: function get(prop) {
|
|
152
|
+
return el[OFI].img[prop ? prop : 'src'];
|
|
153
|
+
},
|
|
154
|
+
set: function set(value, prop) {
|
|
155
|
+
el[OFI].img[prop ? prop : 'src'] = value;
|
|
156
|
+
nativeSetAttribute.call(el, ("data-ofi-" + prop), value); // preserve for any future cloneNode
|
|
157
|
+
fixOne(el);
|
|
158
|
+
return value;
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
Object.defineProperty(el, 'src', descriptors);
|
|
162
|
+
Object.defineProperty(el, 'currentSrc', {
|
|
163
|
+
get: function () { return descriptors.get('currentSrc'); }
|
|
164
|
+
});
|
|
165
|
+
Object.defineProperty(el, 'srcset', {
|
|
166
|
+
get: function () { return descriptors.get('srcset'); },
|
|
167
|
+
set: function (ss) { return descriptors.set(ss, 'srcset'); }
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function hijackAttributes() {
|
|
172
|
+
function getOfiImageMaybe(el, name) {
|
|
173
|
+
return el[OFI] && el[OFI].img && (name === 'src' || name === 'srcset') ? el[OFI].img : el;
|
|
174
|
+
}
|
|
175
|
+
if (!supportsObjectPosition) {
|
|
176
|
+
HTMLImageElement.prototype.getAttribute = function (name) {
|
|
177
|
+
return nativeGetAttribute.call(getOfiImageMaybe(this, name), name);
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
HTMLImageElement.prototype.setAttribute = function (name, value) {
|
|
181
|
+
return nativeSetAttribute.call(getOfiImageMaybe(this, name), name, String(value));
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function fix(imgs, opts) {
|
|
187
|
+
var startAutoMode = !autoModeEnabled && !imgs;
|
|
188
|
+
opts = opts || {};
|
|
189
|
+
imgs = imgs || 'img';
|
|
190
|
+
|
|
191
|
+
if ((supportsObjectPosition && !opts.skipTest) || !supportsOFI) {
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// use imgs as a selector or just select all images
|
|
196
|
+
if (imgs === 'img') {
|
|
197
|
+
imgs = document.getElementsByTagName('img');
|
|
198
|
+
} else if (typeof imgs === 'string') {
|
|
199
|
+
imgs = document.querySelectorAll(imgs);
|
|
200
|
+
} else if (!('length' in imgs)) {
|
|
201
|
+
imgs = [imgs];
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// apply fix to all
|
|
205
|
+
for (var i = 0; i < imgs.length; i++) {
|
|
206
|
+
imgs[i][OFI] = imgs[i][OFI] || {
|
|
207
|
+
skipTest: opts.skipTest
|
|
208
|
+
};
|
|
209
|
+
fixOne(imgs[i]);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (startAutoMode) {
|
|
213
|
+
document.body.addEventListener('load', function (e) {
|
|
214
|
+
if (e.target.tagName === 'IMG') {
|
|
215
|
+
fix(e.target, {
|
|
216
|
+
skipTest: opts.skipTest
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
}, true);
|
|
220
|
+
autoModeEnabled = true;
|
|
221
|
+
imgs = 'img'; // reset to a generic selector for watchMQ
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// if requested, watch media queries for object-fit change
|
|
225
|
+
if (opts.watchMQ) {
|
|
226
|
+
window.addEventListener('resize', fix.bind(null, imgs, {
|
|
227
|
+
skipTest: opts.skipTest
|
|
228
|
+
}));
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
fix.supportsObjectFit = supportsObjectFit;
|
|
233
|
+
fix.supportsObjectPosition = supportsObjectPosition;
|
|
234
|
+
|
|
235
|
+
hijackAttributes();
|
|
236
|
+
|
|
237
|
+
var ofi_commonJs = fix;
|
|
238
|
+
|
|
239
|
+
var ofi_commonJs$1 = /*@__PURE__*/getDefaultExportFromCjs(ofi_commonJs);
|
|
240
|
+
|
|
241
|
+
return ofi_commonJs$1;
|
|
242
|
+
|
|
243
|
+
})();
|
|
@@ -0,0 +1,546 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Stickyfill – `position: sticky` polyfill
|
|
3
|
+
* v. 2.1.0 | https://github.com/wilddeer/stickyfill
|
|
4
|
+
* MIT License
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
;(function(window, document) {
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
/*
|
|
11
|
+
* 1. Check if the browser supports `position: sticky` natively or is too old to run the polyfill.
|
|
12
|
+
* If either of these is the case set `seppuku` flag. It will be checked later to disable key features
|
|
13
|
+
* of the polyfill, but the API will remain functional to avoid breaking things.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
17
|
+
|
|
18
|
+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
19
|
+
|
|
20
|
+
var seppuku = false;
|
|
21
|
+
|
|
22
|
+
var isWindowDefined = typeof window !== 'undefined';
|
|
23
|
+
|
|
24
|
+
// The polyfill can’t function properly without `window` or `window.getComputedStyle`.
|
|
25
|
+
if (!isWindowDefined || !window.getComputedStyle) seppuku = true;
|
|
26
|
+
// Dont’t get in a way if the browser supports `position: sticky` natively.
|
|
27
|
+
else {
|
|
28
|
+
(function () {
|
|
29
|
+
var testNode = document.createElement('div');
|
|
30
|
+
|
|
31
|
+
if (['', '-webkit-', '-moz-', '-ms-'].some(function (prefix) {
|
|
32
|
+
try {
|
|
33
|
+
testNode.style.position = prefix + 'sticky';
|
|
34
|
+
} catch (e) {}
|
|
35
|
+
|
|
36
|
+
return testNode.style.position != '';
|
|
37
|
+
})) seppuku = true;
|
|
38
|
+
})();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/*
|
|
42
|
+
* 2. “Global” vars used across the polyfill
|
|
43
|
+
*/
|
|
44
|
+
var isInitialized = false;
|
|
45
|
+
|
|
46
|
+
// Check if Shadow Root constructor exists to make further checks simpler
|
|
47
|
+
var shadowRootExists = typeof ShadowRoot !== 'undefined';
|
|
48
|
+
|
|
49
|
+
// Last saved scroll position
|
|
50
|
+
var scroll = {
|
|
51
|
+
top: null,
|
|
52
|
+
left: null
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
// Array of created Sticky instances
|
|
56
|
+
var stickies = [];
|
|
57
|
+
|
|
58
|
+
/*
|
|
59
|
+
* 3. Utility functions
|
|
60
|
+
*/
|
|
61
|
+
function extend(targetObj, sourceObject) {
|
|
62
|
+
for (var key in sourceObject) {
|
|
63
|
+
if (sourceObject.hasOwnProperty(key)) {
|
|
64
|
+
targetObj[key] = sourceObject[key];
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function parseNumeric(val) {
|
|
70
|
+
return parseFloat(val) || 0;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function getDocOffsetTop(node) {
|
|
74
|
+
var docOffsetTop = 0;
|
|
75
|
+
|
|
76
|
+
while (node) {
|
|
77
|
+
docOffsetTop += node.offsetTop;
|
|
78
|
+
node = node.offsetParent;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return docOffsetTop;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/*
|
|
85
|
+
* 4. Sticky class
|
|
86
|
+
*/
|
|
87
|
+
|
|
88
|
+
var Sticky = function () {
|
|
89
|
+
function Sticky(node) {
|
|
90
|
+
_classCallCheck(this, Sticky);
|
|
91
|
+
|
|
92
|
+
if (!(node instanceof HTMLElement)) throw new Error('First argument must be HTMLElement');
|
|
93
|
+
if (stickies.some(function (sticky) {
|
|
94
|
+
return sticky._node === node;
|
|
95
|
+
})) throw new Error('Stickyfill is already applied to this node');
|
|
96
|
+
|
|
97
|
+
this._node = node;
|
|
98
|
+
this._stickyMode = null;
|
|
99
|
+
this._active = false;
|
|
100
|
+
|
|
101
|
+
stickies.push(this);
|
|
102
|
+
|
|
103
|
+
this.refresh();
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
_createClass(Sticky, [{
|
|
107
|
+
key: 'refresh',
|
|
108
|
+
value: function refresh() {
|
|
109
|
+
if (seppuku || this._removed) return;
|
|
110
|
+
if (this._active) this._deactivate();
|
|
111
|
+
|
|
112
|
+
var node = this._node;
|
|
113
|
+
|
|
114
|
+
/*
|
|
115
|
+
* 1. Save node computed props
|
|
116
|
+
*/
|
|
117
|
+
var nodeComputedStyle = getComputedStyle(node);
|
|
118
|
+
var nodeComputedProps = {
|
|
119
|
+
position: nodeComputedStyle.position,
|
|
120
|
+
top: nodeComputedStyle.top,
|
|
121
|
+
display: nodeComputedStyle.display,
|
|
122
|
+
marginTop: nodeComputedStyle.marginTop,
|
|
123
|
+
marginBottom: nodeComputedStyle.marginBottom,
|
|
124
|
+
marginLeft: nodeComputedStyle.marginLeft,
|
|
125
|
+
marginRight: nodeComputedStyle.marginRight,
|
|
126
|
+
cssFloat: nodeComputedStyle.cssFloat
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
/*
|
|
130
|
+
* 2. Check if the node can be activated
|
|
131
|
+
*/
|
|
132
|
+
if (isNaN(parseFloat(nodeComputedProps.top)) || nodeComputedProps.display == 'table-cell' || nodeComputedProps.display == 'none') return;
|
|
133
|
+
|
|
134
|
+
this._active = true;
|
|
135
|
+
|
|
136
|
+
/*
|
|
137
|
+
* 3. Check if the current node position is `sticky`. If it is, it means that the browser supports sticky positioning,
|
|
138
|
+
* but the polyfill was force-enabled. We set the node’s position to `static` before continuing, so that the node
|
|
139
|
+
* is in it’s initial position when we gather its params.
|
|
140
|
+
*/
|
|
141
|
+
var originalPosition = node.style.position;
|
|
142
|
+
if (nodeComputedStyle.position == 'sticky' || nodeComputedStyle.position == '-webkit-sticky') node.style.position = 'static';
|
|
143
|
+
|
|
144
|
+
/*
|
|
145
|
+
* 4. Get necessary node parameters
|
|
146
|
+
*/
|
|
147
|
+
var referenceNode = node.parentNode;
|
|
148
|
+
var parentNode = shadowRootExists && referenceNode instanceof ShadowRoot ? referenceNode.host : referenceNode;
|
|
149
|
+
var nodeWinOffset = node.getBoundingClientRect();
|
|
150
|
+
var parentWinOffset = parentNode.getBoundingClientRect();
|
|
151
|
+
var parentComputedStyle = getComputedStyle(parentNode);
|
|
152
|
+
|
|
153
|
+
this._parent = {
|
|
154
|
+
node: parentNode,
|
|
155
|
+
styles: {
|
|
156
|
+
position: parentNode.style.position
|
|
157
|
+
},
|
|
158
|
+
offsetHeight: parentNode.offsetHeight
|
|
159
|
+
};
|
|
160
|
+
this._offsetToWindow = {
|
|
161
|
+
left: nodeWinOffset.left,
|
|
162
|
+
right: document.documentElement.clientWidth - nodeWinOffset.right
|
|
163
|
+
};
|
|
164
|
+
this._offsetToParent = {
|
|
165
|
+
top: nodeWinOffset.top - parentWinOffset.top - parseNumeric(parentComputedStyle.borderTopWidth),
|
|
166
|
+
left: nodeWinOffset.left - parentWinOffset.left - parseNumeric(parentComputedStyle.borderLeftWidth),
|
|
167
|
+
right: -nodeWinOffset.right + parentWinOffset.right - parseNumeric(parentComputedStyle.borderRightWidth)
|
|
168
|
+
};
|
|
169
|
+
this._styles = {
|
|
170
|
+
position: originalPosition,
|
|
171
|
+
top: node.style.top,
|
|
172
|
+
bottom: node.style.bottom,
|
|
173
|
+
left: node.style.left,
|
|
174
|
+
right: node.style.right,
|
|
175
|
+
width: node.style.width,
|
|
176
|
+
marginTop: node.style.marginTop,
|
|
177
|
+
marginLeft: node.style.marginLeft,
|
|
178
|
+
marginRight: node.style.marginRight
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
var nodeTopValue = parseNumeric(nodeComputedProps.top);
|
|
182
|
+
this._limits = {
|
|
183
|
+
start: nodeWinOffset.top + window.pageYOffset - nodeTopValue,
|
|
184
|
+
end: parentWinOffset.top + window.pageYOffset + parentNode.offsetHeight - parseNumeric(parentComputedStyle.borderBottomWidth) - node.offsetHeight - nodeTopValue - parseNumeric(nodeComputedProps.marginBottom)
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
/*
|
|
188
|
+
* 5. Ensure that the node will be positioned relatively to the parent node
|
|
189
|
+
*/
|
|
190
|
+
var parentPosition = parentComputedStyle.position;
|
|
191
|
+
|
|
192
|
+
if (parentPosition != 'absolute' && parentPosition != 'relative') {
|
|
193
|
+
parentNode.style.position = 'relative';
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/*
|
|
197
|
+
* 6. Recalc node position.
|
|
198
|
+
* It’s important to do this before clone injection to avoid scrolling bug in Chrome.
|
|
199
|
+
*/
|
|
200
|
+
this._recalcPosition();
|
|
201
|
+
|
|
202
|
+
/*
|
|
203
|
+
* 7. Create a clone
|
|
204
|
+
*/
|
|
205
|
+
var clone = this._clone = {};
|
|
206
|
+
clone.node = document.createElement('div');
|
|
207
|
+
|
|
208
|
+
// Apply styles to the clone
|
|
209
|
+
extend(clone.node.style, {
|
|
210
|
+
width: nodeWinOffset.right - nodeWinOffset.left + 'px',
|
|
211
|
+
height: nodeWinOffset.bottom - nodeWinOffset.top + 'px',
|
|
212
|
+
marginTop: nodeComputedProps.marginTop,
|
|
213
|
+
marginBottom: nodeComputedProps.marginBottom,
|
|
214
|
+
marginLeft: nodeComputedProps.marginLeft,
|
|
215
|
+
marginRight: nodeComputedProps.marginRight,
|
|
216
|
+
cssFloat: nodeComputedProps.cssFloat,
|
|
217
|
+
padding: 0,
|
|
218
|
+
border: 0,
|
|
219
|
+
borderSpacing: 0,
|
|
220
|
+
fontSize: '1em',
|
|
221
|
+
position: 'static'
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
referenceNode.insertBefore(clone.node, node);
|
|
225
|
+
clone.docOffsetTop = getDocOffsetTop(clone.node);
|
|
226
|
+
}
|
|
227
|
+
}, {
|
|
228
|
+
key: '_recalcPosition',
|
|
229
|
+
value: function _recalcPosition() {
|
|
230
|
+
if (!this._active || this._removed) return;
|
|
231
|
+
|
|
232
|
+
var stickyMode = scroll.top <= this._limits.start ? 'start' : scroll.top >= this._limits.end ? 'end' : 'middle';
|
|
233
|
+
|
|
234
|
+
if (this._stickyMode == stickyMode) return;
|
|
235
|
+
|
|
236
|
+
switch (stickyMode) {
|
|
237
|
+
case 'start':
|
|
238
|
+
extend(this._node.style, {
|
|
239
|
+
position: 'absolute',
|
|
240
|
+
left: this._offsetToParent.left + 'px',
|
|
241
|
+
right: this._offsetToParent.right + 'px',
|
|
242
|
+
top: this._offsetToParent.top + 'px',
|
|
243
|
+
bottom: 'auto',
|
|
244
|
+
width: 'auto',
|
|
245
|
+
marginLeft: 0,
|
|
246
|
+
marginRight: 0,
|
|
247
|
+
marginTop: 0
|
|
248
|
+
});
|
|
249
|
+
break;
|
|
250
|
+
|
|
251
|
+
case 'middle':
|
|
252
|
+
extend(this._node.style, {
|
|
253
|
+
position: 'fixed',
|
|
254
|
+
left: this._offsetToWindow.left + 'px',
|
|
255
|
+
right: this._offsetToWindow.right + 'px',
|
|
256
|
+
top: this._styles.top,
|
|
257
|
+
bottom: 'auto',
|
|
258
|
+
width: 'auto',
|
|
259
|
+
marginLeft: 0,
|
|
260
|
+
marginRight: 0,
|
|
261
|
+
marginTop: 0
|
|
262
|
+
});
|
|
263
|
+
break;
|
|
264
|
+
|
|
265
|
+
case 'end':
|
|
266
|
+
extend(this._node.style, {
|
|
267
|
+
position: 'absolute',
|
|
268
|
+
left: this._offsetToParent.left + 'px',
|
|
269
|
+
right: this._offsetToParent.right + 'px',
|
|
270
|
+
top: 'auto',
|
|
271
|
+
bottom: 0,
|
|
272
|
+
width: 'auto',
|
|
273
|
+
marginLeft: 0,
|
|
274
|
+
marginRight: 0
|
|
275
|
+
});
|
|
276
|
+
break;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
this._stickyMode = stickyMode;
|
|
280
|
+
}
|
|
281
|
+
}, {
|
|
282
|
+
key: '_fastCheck',
|
|
283
|
+
value: function _fastCheck() {
|
|
284
|
+
if (!this._active || this._removed) return;
|
|
285
|
+
|
|
286
|
+
if (Math.abs(getDocOffsetTop(this._clone.node) - this._clone.docOffsetTop) > 1 || Math.abs(this._parent.node.offsetHeight - this._parent.offsetHeight) > 1) this.refresh();
|
|
287
|
+
}
|
|
288
|
+
}, {
|
|
289
|
+
key: '_deactivate',
|
|
290
|
+
value: function _deactivate() {
|
|
291
|
+
var _this = this;
|
|
292
|
+
|
|
293
|
+
if (!this._active || this._removed) return;
|
|
294
|
+
|
|
295
|
+
this._clone.node.parentNode.removeChild(this._clone.node);
|
|
296
|
+
delete this._clone;
|
|
297
|
+
|
|
298
|
+
extend(this._node.style, this._styles);
|
|
299
|
+
delete this._styles;
|
|
300
|
+
|
|
301
|
+
// Check whether element’s parent node is used by other stickies.
|
|
302
|
+
// If not, restore parent node’s styles.
|
|
303
|
+
if (!stickies.some(function (sticky) {
|
|
304
|
+
return sticky !== _this && sticky._parent && sticky._parent.node === _this._parent.node;
|
|
305
|
+
})) {
|
|
306
|
+
extend(this._parent.node.style, this._parent.styles);
|
|
307
|
+
}
|
|
308
|
+
delete this._parent;
|
|
309
|
+
|
|
310
|
+
this._stickyMode = null;
|
|
311
|
+
this._active = false;
|
|
312
|
+
|
|
313
|
+
delete this._offsetToWindow;
|
|
314
|
+
delete this._offsetToParent;
|
|
315
|
+
delete this._limits;
|
|
316
|
+
}
|
|
317
|
+
}, {
|
|
318
|
+
key: 'remove',
|
|
319
|
+
value: function remove() {
|
|
320
|
+
var _this2 = this;
|
|
321
|
+
|
|
322
|
+
this._deactivate();
|
|
323
|
+
|
|
324
|
+
stickies.some(function (sticky, index) {
|
|
325
|
+
if (sticky._node === _this2._node) {
|
|
326
|
+
stickies.splice(index, 1);
|
|
327
|
+
return true;
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
this._removed = true;
|
|
332
|
+
}
|
|
333
|
+
}]);
|
|
334
|
+
|
|
335
|
+
return Sticky;
|
|
336
|
+
}();
|
|
337
|
+
|
|
338
|
+
/*
|
|
339
|
+
* 5. Stickyfill API
|
|
340
|
+
*/
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
var Stickyfill = {
|
|
344
|
+
stickies: stickies,
|
|
345
|
+
Sticky: Sticky,
|
|
346
|
+
|
|
347
|
+
forceSticky: function forceSticky() {
|
|
348
|
+
seppuku = false;
|
|
349
|
+
init();
|
|
350
|
+
|
|
351
|
+
this.refreshAll();
|
|
352
|
+
},
|
|
353
|
+
addOne: function addOne(node) {
|
|
354
|
+
// Check whether it’s a node
|
|
355
|
+
if (!(node instanceof HTMLElement)) {
|
|
356
|
+
// Maybe it’s a node list of some sort?
|
|
357
|
+
// Take first node from the list then
|
|
358
|
+
if (node.length && node[0]) node = node[0];else return;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// Check if Stickyfill is already applied to the node
|
|
362
|
+
// and return existing sticky
|
|
363
|
+
for (var i = 0; i < stickies.length; i++) {
|
|
364
|
+
if (stickies[i]._node === node) return stickies[i];
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// Create and return new sticky
|
|
368
|
+
return new Sticky(node);
|
|
369
|
+
},
|
|
370
|
+
add: function add(nodeList) {
|
|
371
|
+
// If it’s a node make an array of one node
|
|
372
|
+
if (nodeList instanceof HTMLElement) nodeList = [nodeList];
|
|
373
|
+
// Check if the argument is an iterable of some sort
|
|
374
|
+
if (!nodeList.length) return;
|
|
375
|
+
|
|
376
|
+
// Add every element as a sticky and return an array of created Sticky instances
|
|
377
|
+
var addedStickies = [];
|
|
378
|
+
|
|
379
|
+
var _loop = function _loop(i) {
|
|
380
|
+
var node = nodeList[i];
|
|
381
|
+
|
|
382
|
+
// If it’s not an HTMLElement – create an empty element to preserve 1-to-1
|
|
383
|
+
// correlation with input list
|
|
384
|
+
if (!(node instanceof HTMLElement)) {
|
|
385
|
+
addedStickies.push(void 0);
|
|
386
|
+
return 'continue';
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// If Stickyfill is already applied to the node
|
|
390
|
+
// add existing sticky
|
|
391
|
+
if (stickies.some(function (sticky) {
|
|
392
|
+
if (sticky._node === node) {
|
|
393
|
+
addedStickies.push(sticky);
|
|
394
|
+
return true;
|
|
395
|
+
}
|
|
396
|
+
})) return 'continue';
|
|
397
|
+
|
|
398
|
+
// Create and add new sticky
|
|
399
|
+
addedStickies.push(new Sticky(node));
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
for (var i = 0; i < nodeList.length; i++) {
|
|
403
|
+
var _ret2 = _loop(i);
|
|
404
|
+
|
|
405
|
+
if (_ret2 === 'continue') continue;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
return addedStickies;
|
|
409
|
+
},
|
|
410
|
+
refreshAll: function refreshAll() {
|
|
411
|
+
stickies.forEach(function (sticky) {
|
|
412
|
+
return sticky.refresh();
|
|
413
|
+
});
|
|
414
|
+
},
|
|
415
|
+
removeOne: function removeOne(node) {
|
|
416
|
+
// Check whether it’s a node
|
|
417
|
+
if (!(node instanceof HTMLElement)) {
|
|
418
|
+
// Maybe it’s a node list of some sort?
|
|
419
|
+
// Take first node from the list then
|
|
420
|
+
if (node.length && node[0]) node = node[0];else return;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// Remove the stickies bound to the nodes in the list
|
|
424
|
+
stickies.some(function (sticky) {
|
|
425
|
+
if (sticky._node === node) {
|
|
426
|
+
sticky.remove();
|
|
427
|
+
return true;
|
|
428
|
+
}
|
|
429
|
+
});
|
|
430
|
+
},
|
|
431
|
+
remove: function remove(nodeList) {
|
|
432
|
+
// If it’s a node make an array of one node
|
|
433
|
+
if (nodeList instanceof HTMLElement) nodeList = [nodeList];
|
|
434
|
+
// Check if the argument is an iterable of some sort
|
|
435
|
+
if (!nodeList.length) return;
|
|
436
|
+
|
|
437
|
+
// Remove the stickies bound to the nodes in the list
|
|
438
|
+
|
|
439
|
+
var _loop2 = function _loop2(i) {
|
|
440
|
+
var node = nodeList[i];
|
|
441
|
+
|
|
442
|
+
stickies.some(function (sticky) {
|
|
443
|
+
if (sticky._node === node) {
|
|
444
|
+
sticky.remove();
|
|
445
|
+
return true;
|
|
446
|
+
}
|
|
447
|
+
});
|
|
448
|
+
};
|
|
449
|
+
|
|
450
|
+
for (var i = 0; i < nodeList.length; i++) {
|
|
451
|
+
_loop2(i);
|
|
452
|
+
}
|
|
453
|
+
},
|
|
454
|
+
removeAll: function removeAll() {
|
|
455
|
+
while (stickies.length) {
|
|
456
|
+
stickies[0].remove();
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
};
|
|
460
|
+
|
|
461
|
+
/*
|
|
462
|
+
* 6. Setup events (unless the polyfill was disabled)
|
|
463
|
+
*/
|
|
464
|
+
function init() {
|
|
465
|
+
if (isInitialized) {
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
isInitialized = true;
|
|
470
|
+
|
|
471
|
+
// Watch for scroll position changes and trigger recalc/refresh if needed
|
|
472
|
+
function checkScroll() {
|
|
473
|
+
if (window.pageXOffset != scroll.left) {
|
|
474
|
+
scroll.top = window.pageYOffset;
|
|
475
|
+
scroll.left = window.pageXOffset;
|
|
476
|
+
|
|
477
|
+
Stickyfill.refreshAll();
|
|
478
|
+
} else if (window.pageYOffset != scroll.top) {
|
|
479
|
+
scroll.top = window.pageYOffset;
|
|
480
|
+
scroll.left = window.pageXOffset;
|
|
481
|
+
|
|
482
|
+
// recalc position for all stickies
|
|
483
|
+
stickies.forEach(function (sticky) {
|
|
484
|
+
return sticky._recalcPosition();
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
checkScroll();
|
|
490
|
+
window.addEventListener('scroll', checkScroll);
|
|
491
|
+
|
|
492
|
+
// Watch for window resizes and device orientation changes and trigger refresh
|
|
493
|
+
window.addEventListener('resize', Stickyfill.refreshAll);
|
|
494
|
+
window.addEventListener('orientationchange', Stickyfill.refreshAll);
|
|
495
|
+
|
|
496
|
+
//Fast dirty check for layout changes every 500ms
|
|
497
|
+
var fastCheckTimer = void 0;
|
|
498
|
+
|
|
499
|
+
function startFastCheckTimer() {
|
|
500
|
+
fastCheckTimer = setInterval(function () {
|
|
501
|
+
stickies.forEach(function (sticky) {
|
|
502
|
+
return sticky._fastCheck();
|
|
503
|
+
});
|
|
504
|
+
}, 500);
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
function stopFastCheckTimer() {
|
|
508
|
+
clearInterval(fastCheckTimer);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
var docHiddenKey = void 0;
|
|
512
|
+
var visibilityChangeEventName = void 0;
|
|
513
|
+
|
|
514
|
+
if ('hidden' in document) {
|
|
515
|
+
docHiddenKey = 'hidden';
|
|
516
|
+
visibilityChangeEventName = 'visibilitychange';
|
|
517
|
+
} else if ('webkitHidden' in document) {
|
|
518
|
+
docHiddenKey = 'webkitHidden';
|
|
519
|
+
visibilityChangeEventName = 'webkitvisibilitychange';
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
if (visibilityChangeEventName) {
|
|
523
|
+
if (!document[docHiddenKey]) startFastCheckTimer();
|
|
524
|
+
|
|
525
|
+
document.addEventListener(visibilityChangeEventName, function () {
|
|
526
|
+
if (document[docHiddenKey]) {
|
|
527
|
+
stopFastCheckTimer();
|
|
528
|
+
} else {
|
|
529
|
+
startFastCheckTimer();
|
|
530
|
+
}
|
|
531
|
+
});
|
|
532
|
+
} else startFastCheckTimer();
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
if (!seppuku) init();
|
|
536
|
+
|
|
537
|
+
/*
|
|
538
|
+
* 7. Expose Stickyfill
|
|
539
|
+
*/
|
|
540
|
+
if (typeof module != 'undefined' && module.exports) {
|
|
541
|
+
module.exports = Stickyfill;
|
|
542
|
+
} else if (isWindowDefined) {
|
|
543
|
+
window.Stickyfill = Stickyfill;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
})(window, document);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pageboard/html",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"repository": {
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"dependencies": {},
|
|
17
17
|
"devDependencies": {
|
|
18
18
|
"nouislider": "^15.7.1",
|
|
19
|
-
"postinstall": "^0.
|
|
19
|
+
"postinstall": "^0.10.3"
|
|
20
20
|
},
|
|
21
21
|
"postinstall": {},
|
|
22
22
|
"prepare": {
|
package/ui/image.js
CHANGED
|
@@ -9,27 +9,20 @@ const HTMLElementImageConstructor = Superclass => class extends Superclass {
|
|
|
9
9
|
|
|
10
10
|
#defer;
|
|
11
11
|
|
|
12
|
-
static getZoom({ w, h, rw, rh, fit }) {
|
|
13
|
-
let z = 100;
|
|
14
|
-
if (!rw && !rh) return z;
|
|
15
|
-
if (!rw) rw = rh * w / h;
|
|
16
|
-
if (!rh) rh = rw * h / w;
|
|
17
|
-
z = Math.ceil((fit == "contain" ? Math.min : Math.max)(rw / w, rh / h) * 100 * (window.devicePixelRatio || 1));
|
|
18
|
-
// svg need to be resized to scale to its intrinsic dimension
|
|
19
|
-
if (z > 100) z = 100;
|
|
20
|
-
const zstep = 5;
|
|
21
|
-
z = Math.ceil(z / zstep) * zstep;
|
|
22
|
-
return z;
|
|
23
|
-
}
|
|
24
12
|
get dimensions() {
|
|
13
|
+
// dimension in pixels of the (extracted) source image
|
|
25
14
|
let w = parseInt(this.dataset.width);
|
|
26
15
|
let h = parseInt(this.dataset.height);
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
h = Math.round(h *
|
|
16
|
+
const { crop } = this;
|
|
17
|
+
if (crop.w != 100) {
|
|
18
|
+
w = Math.round(w * crop.w / 100);
|
|
19
|
+
}
|
|
20
|
+
if (crop.h != 100) {
|
|
21
|
+
h = Math.round(h * crop.h / 100);
|
|
22
|
+
}
|
|
23
|
+
if (crop.z != 100) {
|
|
24
|
+
w = Math.round(w * crop.z / 100);
|
|
25
|
+
h = Math.round(h * crop.z / 100);
|
|
33
26
|
}
|
|
34
27
|
return { w, h };
|
|
35
28
|
}
|
|
@@ -53,12 +46,12 @@ const HTMLElementImageConstructor = Superclass => class extends Superclass {
|
|
|
53
46
|
});
|
|
54
47
|
}
|
|
55
48
|
get crop() {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
49
|
+
const defs = [50, 50, 100, 100, 100];
|
|
50
|
+
const list = (this.dataset.crop || ";;;;").split(";").map(x => parseFloat(x));
|
|
51
|
+
for (let i = 0; i < defs.length; i++) {
|
|
52
|
+
if (Number.isNaN(list[i])) list[i] = defs[i];
|
|
53
|
+
}
|
|
54
|
+
const [x, y, w, h, z] = list;
|
|
62
55
|
return { x, y, w, h, z };
|
|
63
56
|
}
|
|
64
57
|
set crop({ x, y, w, h, z }) {
|
|
@@ -99,6 +92,44 @@ const HTMLElementImageConstructor = Superclass => class extends Superclass {
|
|
|
99
92
|
else return src;
|
|
100
93
|
}
|
|
101
94
|
|
|
95
|
+
requestSrc(srcLoc) {
|
|
96
|
+
const { crop, fit } = this;
|
|
97
|
+
const { w, h } = this.dimensions;
|
|
98
|
+
const r = {};
|
|
99
|
+
if (!Number.isNaN(w) && !Number.isNaN(h)) {
|
|
100
|
+
if (fit == "none") {
|
|
101
|
+
r.width = w;
|
|
102
|
+
r.height = h;
|
|
103
|
+
} else {
|
|
104
|
+
const rect = this.getBoundingClientRect();
|
|
105
|
+
r.width = rect.width;
|
|
106
|
+
r.height = rect.height;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (!r.width && !r.height) {
|
|
110
|
+
// don't show
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
if (crop.x != 50 || crop.y != 50 || crop.w != 100 || crop.h != 100) {
|
|
114
|
+
if (Math.round((crop.x - crop.w / 2) * 100) < 0 || Math.round((crop.x + crop.w / 2) * 100) > 10000) {
|
|
115
|
+
crop.w = 2 * Math.min(crop.x, 100 - crop.x);
|
|
116
|
+
}
|
|
117
|
+
if (Math.round((crop.y - crop.h / 2) * 100) < 0 || Math.round((crop.y + crop.h / 2) * 100) > 10000) {
|
|
118
|
+
crop.h = 2 * Math.min(crop.y, 100 - crop.y);
|
|
119
|
+
}
|
|
120
|
+
srcLoc.query.ex = `x-${crop.x}_y-${crop.y}_w-${crop.w}_h-${crop.h}`;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (!r.width) r.width = r.height * w / h;
|
|
124
|
+
if (!r.height) r.height = r.width * h / w;
|
|
125
|
+
const clientHintWidth = Math.ceil(
|
|
126
|
+
(fit == "contain" ? Math.min : Math.max)(r.width / w, r.height / h)
|
|
127
|
+
* w * (window.devicePixelRatio || 1)
|
|
128
|
+
);
|
|
129
|
+
srcLoc.query.rs = `w-${clientHintWidth}`; // max, min ?
|
|
130
|
+
return srcLoc.toString();
|
|
131
|
+
}
|
|
132
|
+
|
|
102
133
|
reveal(state) {
|
|
103
134
|
const img = this.image;
|
|
104
135
|
if (!this.options.src) {
|
|
@@ -108,47 +139,15 @@ const HTMLElementImageConstructor = Superclass => class extends Superclass {
|
|
|
108
139
|
if (this.classList.contains('loading')) {
|
|
109
140
|
return;
|
|
110
141
|
}
|
|
111
|
-
const
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
if (
|
|
116
|
-
loc = Page.parse({
|
|
117
|
-
pathname: "/.api/image",
|
|
118
|
-
query: {
|
|
119
|
-
url: this.options.src
|
|
120
|
-
}
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if (r.x != 50 || r.y != 50 || r.w != 100 || r.h != 100) {
|
|
125
|
-
if (Math.round((r.x - r.w / 2) * 100) < 0 || Math.round((r.x + r.w / 2) * 100) > 10000) {
|
|
126
|
-
r.w = 2 * Math.min(r.x, 100 - r.x);
|
|
127
|
-
}
|
|
128
|
-
if (Math.round((r.y - r.h / 2) * 100) < 0 || Math.round((r.y + r.h / 2) * 100) > 10000) {
|
|
129
|
-
r.h = 2 * Math.min(r.y, 100 - r.y);
|
|
130
|
-
}
|
|
131
|
-
loc.query.ex = `x-${r.x}_y-${r.y}_w-${r.w}_h-${r.h}`;
|
|
132
|
-
}
|
|
133
|
-
const { w, h } = this.dimensions;
|
|
134
|
-
if (fit == "none") {
|
|
135
|
-
loc.query.rs = `z-${r.z}`;
|
|
136
|
-
} else if (!Number.isNaN(w) && !Number.isNaN(h)) {
|
|
137
|
-
const rect = this.getBoundingClientRect();
|
|
138
|
-
const rw = rect.width;
|
|
139
|
-
const rh = rect.height;
|
|
140
|
-
if (rw == 0 && rh == 0) {
|
|
141
|
-
// don't show
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
loc.query.rs = "z-" + this.constructor.getZoom({ w, h, rw, rh, fit });
|
|
145
|
-
}
|
|
146
|
-
const curSrc = loc.toString();
|
|
147
|
-
if (curSrc != this.currentSrc) {
|
|
142
|
+
const srcLoc = Page.parse(this.options.src);
|
|
143
|
+
const reqSrc = this.requestSrc(srcLoc);
|
|
144
|
+
if (!reqSrc) {
|
|
145
|
+
img.setAttribute('src', '');
|
|
146
|
+
} else if (reqSrc != this.currentSrc) {
|
|
148
147
|
this.classList.add('loading');
|
|
149
148
|
this.#defer?.resolve();
|
|
150
149
|
this.#defer = new Deferred();
|
|
151
|
-
img.setAttribute('src',
|
|
150
|
+
img.setAttribute('src', reqSrc);
|
|
152
151
|
return this.#defer;
|
|
153
152
|
}
|
|
154
153
|
}
|
package/ui/input-file.js
CHANGED
|
@@ -73,9 +73,10 @@ class HTMLElementInputFile extends Page.create(HTMLInputElement) {
|
|
|
73
73
|
this.#defer = null;
|
|
74
74
|
};
|
|
75
75
|
const pass = (obj) => {
|
|
76
|
-
if (!obj.
|
|
77
|
-
|
|
78
|
-
|
|
76
|
+
if (!obj.hrefs?.length) {
|
|
77
|
+
return fail(new Error("File rejected"));
|
|
78
|
+
}
|
|
79
|
+
this.value = obj.hrefs[0]?.pathname;
|
|
79
80
|
field.classList.add('success');
|
|
80
81
|
field.classList.remove('loading');
|
|
81
82
|
this.#xhr = null;
|
|
@@ -124,7 +125,7 @@ class HTMLElementInputFile extends Page.create(HTMLInputElement) {
|
|
|
124
125
|
fail(err);
|
|
125
126
|
});
|
|
126
127
|
try {
|
|
127
|
-
xhr.open("POST",
|
|
128
|
+
xhr.open("POST", `/@api/upload/${this.id}`, true);
|
|
128
129
|
xhr.setRequestHeader('Accept', "application/json; q=1.0");
|
|
129
130
|
xhr.send(fd);
|
|
130
131
|
this.#xhr = xhr;
|
package/ui/layout.js
CHANGED
|
@@ -14,48 +14,16 @@ class HTMLElementLayout extends Page.create(HTMLDivElement) {
|
|
|
14
14
|
this.style.backgroundImage = '';
|
|
15
15
|
return;
|
|
16
16
|
}
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
pathname: "/.api/image",
|
|
24
|
-
query: {
|
|
25
|
-
url: this.options.src
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
if (r.x != 50 || r.y != 50 || r.w != 100 || r.h != 100) {
|
|
31
|
-
if (Math.round((r.x - r.w / 2) * 100) < 0 || Math.round((r.x + r.w / 2) * 100) > 10000) {
|
|
32
|
-
r.w = 2 * Math.min(r.x, 100 - r.x);
|
|
33
|
-
}
|
|
34
|
-
if (Math.round((r.y - r.h / 2) * 100) < 0 || Math.round((r.y + r.h / 2) * 100) > 10000) {
|
|
35
|
-
r.h = 2 * Math.min(r.y, 100 - r.y);
|
|
36
|
-
}
|
|
37
|
-
loc.query.ex = `x-${r.x}_y-${r.y}_w-${r.w}_h-${r.h}`;
|
|
38
|
-
}
|
|
39
|
-
const {w, h} = this.dimensions;
|
|
40
|
-
if (fit == "none") {
|
|
41
|
-
loc.query.rs = `z-${r.z}`;
|
|
42
|
-
} else if (!Number.isNaN(w) && !Number.isNaN(h)) {
|
|
43
|
-
const rect = this.getBoundingClientRect();
|
|
44
|
-
const rw = rect.width;
|
|
45
|
-
const rh = rect.height;
|
|
46
|
-
if (rw == 0 && rh == 0) {
|
|
47
|
-
// don't show
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
loc.query.rs = "z-" + HTMLElementLayout.getZoom({w, h, rw, rh, fit});
|
|
17
|
+
const srcLoc = Page.parse(this.options.src);
|
|
18
|
+
const reqSrc = this.requestSrc(srcLoc);
|
|
19
|
+
try {
|
|
20
|
+
this.currentSrc = reqSrc;
|
|
21
|
+
} catch (e) {
|
|
22
|
+
// pass
|
|
51
23
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
this.currentSrc = curSrc;
|
|
56
|
-
} catch(e) {
|
|
57
|
-
// pass
|
|
58
|
-
}
|
|
24
|
+
if (!reqSrc) {
|
|
25
|
+
this.style.backgroundImage = '';
|
|
26
|
+
} else if (reqSrc != this.currentSrc) {
|
|
59
27
|
this.#defer?.resolve();
|
|
60
28
|
this.#defer = new Deferred();
|
|
61
29
|
const img = new Image();
|
|
@@ -63,8 +31,8 @@ class HTMLElementLayout extends Page.create(HTMLDivElement) {
|
|
|
63
31
|
img.addEventListener('error',
|
|
64
32
|
e => this.#defer.reject(new Error(this.currentSrc))
|
|
65
33
|
);
|
|
66
|
-
img.src =
|
|
67
|
-
this.style.backgroundImage = `url("${
|
|
34
|
+
img.src = reqSrc;
|
|
35
|
+
this.style.backgroundImage = `url("${reqSrc}")`;
|
|
68
36
|
return this.#defer;
|
|
69
37
|
}
|
|
70
38
|
}
|
|
@@ -74,14 +42,13 @@ class HTMLElementLayout extends Page.create(HTMLDivElement) {
|
|
|
74
42
|
}
|
|
75
43
|
|
|
76
44
|
(function(HTMLElementImage) {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
45
|
+
for (const name of ['crop', 'dimensions', 'requestSrc']) {
|
|
46
|
+
Object.defineProperty(
|
|
47
|
+
HTMLElementLayout.prototype,
|
|
48
|
+
name,
|
|
49
|
+
Object.getOwnPropertyDescriptor(HTMLElementImage.prototype, name)
|
|
50
|
+
);
|
|
51
|
+
}
|
|
85
52
|
})(window.customElements.get('element-image'));
|
|
86
53
|
|
|
87
54
|
Page.define(`element-layout`, HTMLElementLayout, 'div');
|
package/ui/pagination.js
CHANGED
|
@@ -9,7 +9,7 @@ class HTMLElementPagination extends Page.create(HTMLAnchorElement) {
|
|
|
9
9
|
#update(state) {
|
|
10
10
|
const { fetch } = this.dataset;
|
|
11
11
|
const node = this.ownerDocument.querySelector(
|
|
12
|
-
`element-template[action="
|
|
12
|
+
`element-template[action="/@api/query/${fetch}"]`
|
|
13
13
|
);
|
|
14
14
|
if (!node) {
|
|
15
15
|
console.warn("pagination does not find fetch node", fetch);
|