@pageboard/html 0.15.14 → 0.16.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/consent.js +56 -8
- package/elements/embed.js +5 -0
- package/elements/form.js +14 -10
- package/elements/image.js +1 -2
- package/elements/inlines.js +1 -1
- package/elements/inputs.js +90 -4
- package/elements/link.js +6 -2
- package/elements/medialist.js +17 -2
- package/elements/menu.js +3 -1
- package/elements/page.js +6 -10
- package/package.json +7 -8
- package/ui/consent.css +10 -3
- package/ui/consent.js +53 -56
- package/ui/embed.js +6 -3
- package/ui/form.js +20 -13
- package/ui/inlines.css +3 -0
- package/ui/layout.js +1 -0
- package/ui/medialist.css +47 -8
- package/ui/storage.js +18 -33
- package/lib/formdata.js +0 -21
- package/lib/nouislider.css +0 -304
- package/lib/nouislider.js +0 -2341
- package/lib/object-fit-images.js +0 -243
- package/lib/stickyfill.js +0 -546
- package/ui/item.css +0 -448
package/elements/consent.js
CHANGED
|
@@ -2,7 +2,7 @@ exports.consent_form = {
|
|
|
2
2
|
priority: 11,
|
|
3
3
|
title: 'Consent',
|
|
4
4
|
icon: '<i class="handshake icon"></i>',
|
|
5
|
-
group: "block",
|
|
5
|
+
group: "block form",
|
|
6
6
|
menu: 'form',
|
|
7
7
|
properties: {
|
|
8
8
|
transient: {
|
|
@@ -17,44 +17,92 @@ exports.consent_form = {
|
|
|
17
17
|
nodes: "block+"
|
|
18
18
|
},
|
|
19
19
|
html: `<form is="element-consent" class="ui form" data-transient="[transient]">
|
|
20
|
-
<
|
|
20
|
+
<template block-content="content"></template>
|
|
21
|
+
<div class="view"></div>
|
|
21
22
|
</form>`,
|
|
22
23
|
scripts: ['../ui/storage.js', '../ui/consent.js'],
|
|
23
24
|
stylesheets: ['../ui/consent.css']
|
|
24
25
|
};
|
|
25
26
|
|
|
27
|
+
const consents = [];
|
|
28
|
+
|
|
29
|
+
exports.input_radio_consent = {
|
|
30
|
+
title: 'Consent custom',
|
|
31
|
+
icon: '<i class="hand scissors icon"></i>',
|
|
32
|
+
menu: "form",
|
|
33
|
+
group: "block",
|
|
34
|
+
context: 'consent_form//',
|
|
35
|
+
properties: {
|
|
36
|
+
value: {
|
|
37
|
+
title: 'Consent',
|
|
38
|
+
anyOf: [{
|
|
39
|
+
const: 'custom',
|
|
40
|
+
title: 'Custom'
|
|
41
|
+
}, {
|
|
42
|
+
const: 'yes',
|
|
43
|
+
title: 'All'
|
|
44
|
+
}, {
|
|
45
|
+
const: 'no',
|
|
46
|
+
title: 'None'
|
|
47
|
+
}]
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
contents: {
|
|
51
|
+
id: 'label',
|
|
52
|
+
nodes: 'inline*'
|
|
53
|
+
},
|
|
54
|
+
html: `<div class="field">
|
|
55
|
+
<div class="ui radio checkbox">
|
|
56
|
+
<input type="radio" name="consent" value="[value]" id="for-consent-[value]" />
|
|
57
|
+
<label block-content="label" for="for-consent-[value]">Custom</label>
|
|
58
|
+
</div>
|
|
59
|
+
</div>`
|
|
60
|
+
};
|
|
61
|
+
|
|
26
62
|
exports.input_radio_yes = {
|
|
27
|
-
title: '
|
|
63
|
+
title: 'Consent yes',
|
|
28
64
|
icon: '<i class="thumbs up icon"></i>',
|
|
29
65
|
menu: "form",
|
|
30
66
|
group: "block",
|
|
31
67
|
context: 'consent_form//',
|
|
68
|
+
properties: {
|
|
69
|
+
consent: {
|
|
70
|
+
title: 'Consent',
|
|
71
|
+
anyOf: consents
|
|
72
|
+
}
|
|
73
|
+
},
|
|
32
74
|
contents: {
|
|
33
75
|
id: 'label',
|
|
34
76
|
nodes: 'inline*'
|
|
35
77
|
},
|
|
36
78
|
html: `<div class="field">
|
|
37
79
|
<div class="ui radio checkbox">
|
|
38
|
-
<input type="radio" name="consent" value="yes" id="for-consent-yes" />
|
|
39
|
-
<label block-content="label" for="for-consent-yes">Yes</label>
|
|
80
|
+
<input type="radio" name="consent.[consent]" value="yes" id="for-consent-yes-[consent]" />
|
|
81
|
+
<label block-content="label" for="for-consent-yes-[consent]">Yes</label>
|
|
40
82
|
</div>
|
|
41
83
|
</div>`
|
|
42
84
|
};
|
|
43
85
|
|
|
44
86
|
exports.input_radio_no = {
|
|
45
|
-
title: '
|
|
87
|
+
title: 'Consent no',
|
|
46
88
|
icon: '<i class="thumbs down icon"></i>',
|
|
47
89
|
menu: "form",
|
|
48
90
|
group: "block",
|
|
49
91
|
context: 'consent_form//',
|
|
92
|
+
properties: {
|
|
93
|
+
consent: {
|
|
94
|
+
title: 'Consent',
|
|
95
|
+
anyOf: consents
|
|
96
|
+
}
|
|
97
|
+
},
|
|
50
98
|
contents: {
|
|
51
99
|
id: 'label',
|
|
52
100
|
nodes: 'inline*'
|
|
53
101
|
},
|
|
54
102
|
html: `<div class="field">
|
|
55
103
|
<div class="ui radio checkbox">
|
|
56
|
-
<input type="radio" name="consent" value="no" id="for-consent-no" />
|
|
57
|
-
<label block-content="label" for="for-consent-no">No</label>
|
|
104
|
+
<input type="radio" name="consent.[consent]" value="no" id="for-consent-no-[consent]" />
|
|
105
|
+
<label block-content="label" for="for-consent-no-[consent]">No</label>
|
|
58
106
|
</div>
|
|
59
107
|
</div>`
|
|
60
108
|
};
|
package/elements/embed.js
CHANGED
package/elements/form.js
CHANGED
|
@@ -31,15 +31,20 @@ exports.query_form = {
|
|
|
31
31
|
}
|
|
32
32
|
},
|
|
33
33
|
redirection: {
|
|
34
|
-
title: 'Target
|
|
34
|
+
title: 'Target',
|
|
35
35
|
type: 'object',
|
|
36
36
|
properties: {
|
|
37
37
|
url: {
|
|
38
|
-
title: '
|
|
38
|
+
title: 'Address',
|
|
39
39
|
nullable: true,
|
|
40
40
|
type: "string",
|
|
41
|
-
format:
|
|
42
|
-
$helper:
|
|
41
|
+
format: 'uri-reference',
|
|
42
|
+
$helper: {
|
|
43
|
+
name: 'href',
|
|
44
|
+
filter: {
|
|
45
|
+
type: ["link", "file", "archive"]
|
|
46
|
+
}
|
|
47
|
+
}
|
|
43
48
|
},
|
|
44
49
|
parameters: {
|
|
45
50
|
title: 'Parameters',
|
|
@@ -89,8 +94,7 @@ exports.api_form = {
|
|
|
89
94
|
title: 'Hidden',
|
|
90
95
|
description: 'Hidden and disabled\nShown by $query.toggle',
|
|
91
96
|
type: 'boolean',
|
|
92
|
-
default: false
|
|
93
|
-
context: 'template'
|
|
97
|
+
default: false
|
|
94
98
|
},
|
|
95
99
|
action: {
|
|
96
100
|
title: 'Action',
|
|
@@ -177,10 +181,10 @@ exports.api_form = {
|
|
|
177
181
|
id="[name|else:$id]"
|
|
178
182
|
action="/@api/form/[$id]"
|
|
179
183
|
parameters="[action?.request|as:expressions]"
|
|
180
|
-
success="[redirection.parameters|as:query]"
|
|
181
|
-
badrequest="[badrequest.parameters|as:query]"
|
|
182
|
-
unauthorized="[unauthorized.parameters|as:query]"
|
|
183
|
-
notfound="[notfound.parameters|as:query]"
|
|
184
|
+
success="[redirection.parameters|as:query|as:null]"
|
|
185
|
+
badrequest="[badrequest.parameters|as:query|as:null]"
|
|
186
|
+
unauthorized="[unauthorized.parameters|as:query|as:null]"
|
|
187
|
+
notfound="[notfound.parameters|as:query|as:null]"
|
|
184
188
|
class="ui form"></form>`,
|
|
185
189
|
stylesheets: [
|
|
186
190
|
'../ui/components/form.css',
|
package/elements/image.js
CHANGED
|
@@ -128,14 +128,13 @@ exports.image = {
|
|
|
128
128
|
}, {
|
|
129
129
|
id: 'alt',
|
|
130
130
|
title: 'Alternative Text',
|
|
131
|
-
$attr: 'data-alt',
|
|
132
131
|
$helper: {
|
|
133
132
|
name: 'describe'
|
|
134
133
|
}
|
|
135
134
|
}],
|
|
136
135
|
html: `<element-image
|
|
137
136
|
class="[display.fit|or:none] [display.horizontal?] [display.vertical?]"
|
|
138
|
-
data-src="[url]"
|
|
137
|
+
data-src="[url]" data-alt="[$content.alt]"
|
|
139
138
|
data-crop="[crop.x|or:50];[crop.y|or:50];[crop.width|or:100];[crop.height|or:100];[crop.zoom|or:100]"
|
|
140
139
|
>
|
|
141
140
|
<div block-content="legend"></div>
|
package/elements/inlines.js
CHANGED
package/elements/inputs.js
CHANGED
|
@@ -13,8 +13,7 @@ exports.input_button = {
|
|
|
13
13
|
title: 'Type',
|
|
14
14
|
default: 'submit',
|
|
15
15
|
anyOf: [{
|
|
16
|
-
|
|
17
|
-
const: 'submit'
|
|
16
|
+
const: 'submit' // deprecated
|
|
18
17
|
}, {
|
|
19
18
|
title: 'Reset',
|
|
20
19
|
const: 'reset'
|
|
@@ -90,6 +89,93 @@ exports.input_button = {
|
|
|
90
89
|
]
|
|
91
90
|
};
|
|
92
91
|
|
|
92
|
+
exports.input_submit = {
|
|
93
|
+
title: 'Submit',
|
|
94
|
+
icon: '<i class="icons"><i class="hand pointer icon"></i><i class="corner write icon"></i></i>',
|
|
95
|
+
menu: "form",
|
|
96
|
+
group: "block input_field",
|
|
97
|
+
context: 'form//',
|
|
98
|
+
contents: {
|
|
99
|
+
nodes: "inline*",
|
|
100
|
+
marks: "nolink"
|
|
101
|
+
},
|
|
102
|
+
properties: {
|
|
103
|
+
action: {
|
|
104
|
+
title: 'Action',
|
|
105
|
+
type: 'string',
|
|
106
|
+
format: 'pathname',
|
|
107
|
+
nullable: true,
|
|
108
|
+
$helper: {
|
|
109
|
+
name: 'datalist',
|
|
110
|
+
url: '/@api/block/search?type=api_form&limit=20&data.name:not&order=data.name',
|
|
111
|
+
value: '/@api/form/[data.name]',
|
|
112
|
+
title: '[$services.[data.action.method|enc:path].title] / [data.name|else:id]'
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
name: {
|
|
116
|
+
title: "Name",
|
|
117
|
+
description: "The form object key",
|
|
118
|
+
type: "string",
|
|
119
|
+
format: "singleline"
|
|
120
|
+
},
|
|
121
|
+
value: {
|
|
122
|
+
title: "Default value",
|
|
123
|
+
nullable: true,
|
|
124
|
+
type: "string",
|
|
125
|
+
format: "singleline"
|
|
126
|
+
},
|
|
127
|
+
form: {
|
|
128
|
+
title: 'Target form',
|
|
129
|
+
type: 'string',
|
|
130
|
+
format: 'name',
|
|
131
|
+
nullable: true,
|
|
132
|
+
$filter: {
|
|
133
|
+
name: 'action',
|
|
134
|
+
action: 'write'
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
disabled: {
|
|
138
|
+
title: 'Disabled',
|
|
139
|
+
type: 'boolean',
|
|
140
|
+
default: false
|
|
141
|
+
},
|
|
142
|
+
full: {
|
|
143
|
+
title: 'Fluid',
|
|
144
|
+
type: 'boolean',
|
|
145
|
+
default: false
|
|
146
|
+
},
|
|
147
|
+
icon: {
|
|
148
|
+
title: 'Icon',
|
|
149
|
+
type: 'boolean',
|
|
150
|
+
default: false
|
|
151
|
+
},
|
|
152
|
+
compact: {
|
|
153
|
+
title: 'Compact',
|
|
154
|
+
type: 'boolean',
|
|
155
|
+
default: false
|
|
156
|
+
},
|
|
157
|
+
float: {
|
|
158
|
+
title: 'Float',
|
|
159
|
+
anyOf: [{
|
|
160
|
+
type: 'null',
|
|
161
|
+
title: 'No'
|
|
162
|
+
}, {
|
|
163
|
+
const: 'left',
|
|
164
|
+
title: 'Left'
|
|
165
|
+
}, {
|
|
166
|
+
const: 'right',
|
|
167
|
+
title: 'Right'
|
|
168
|
+
}],
|
|
169
|
+
default: null
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
html: '<button type="submit" formaction="[action]" form="[form]" disabled="[disabled]" class="ui [full|alt:fluid:] [icon] [compact] [float|post:%20floated] button" name="[name]" value="[value]">Submit</button>',
|
|
173
|
+
stylesheets: [
|
|
174
|
+
'../ui/components/button.css',
|
|
175
|
+
'../ui/button.css'
|
|
176
|
+
]
|
|
177
|
+
};
|
|
178
|
+
|
|
93
179
|
exports.input_fields = {
|
|
94
180
|
title: 'Input Fields',
|
|
95
181
|
icon: '<i class="icon columns"></i>',
|
|
@@ -206,8 +292,8 @@ exports.input_text = {
|
|
|
206
292
|
nodes: 'inline*'
|
|
207
293
|
},
|
|
208
294
|
patterns: {
|
|
209
|
-
tel: /^(\(\d+\))? *\d+([
|
|
210
|
-
email:
|
|
295
|
+
tel: /^(\(\d+\))? *\d+([ .\-]?\d+)*$/v.source,
|
|
296
|
+
email: /[\w.!#$%&'*+\/=?^`\{\|\}~\-]+@\w(?:[\w\-]{0,61}\w)?(?:\.\w(?:[\w\-]{0,61}\w)?)*/v.source
|
|
211
297
|
},
|
|
212
298
|
html: `<div class="[width|as:colnums|post: wide] field [type|if:eq:hidden]">
|
|
213
299
|
<label block-content="label">Label</label>
|
package/elements/link.js
CHANGED
|
@@ -29,7 +29,9 @@ exports.link = {
|
|
|
29
29
|
nullable: true,
|
|
30
30
|
$helper: {
|
|
31
31
|
name: 'datalist',
|
|
32
|
-
url: '/@api/translate/languages'
|
|
32
|
+
url: '/@api/translate/languages',
|
|
33
|
+
value: '[data.lang]',
|
|
34
|
+
title: '[content.]'
|
|
33
35
|
}
|
|
34
36
|
},
|
|
35
37
|
id: {
|
|
@@ -75,7 +77,9 @@ exports.link_button = {
|
|
|
75
77
|
nullable: true,
|
|
76
78
|
$helper: {
|
|
77
79
|
name: 'datalist',
|
|
78
|
-
url: '/@api/translate/languages'
|
|
80
|
+
url: '/@api/translate/languages',
|
|
81
|
+
value: '[data.lang]',
|
|
82
|
+
title: '[content.]'
|
|
79
83
|
}
|
|
80
84
|
},
|
|
81
85
|
full: {
|
package/elements/medialist.js
CHANGED
|
@@ -3,11 +3,26 @@ exports.medialist = {
|
|
|
3
3
|
priority: 20,
|
|
4
4
|
group: "block",
|
|
5
5
|
icon: '<i class="list icon"></i>',
|
|
6
|
+
properties: {
|
|
7
|
+
size: {
|
|
8
|
+
title: 'Size',
|
|
9
|
+
anyOf: [{
|
|
10
|
+
type: 'null',
|
|
11
|
+
title: 'Normal'
|
|
12
|
+
}, {
|
|
13
|
+
const: 'small',
|
|
14
|
+
title: 'Small'
|
|
15
|
+
}, {
|
|
16
|
+
const: 'large',
|
|
17
|
+
title: 'Large'
|
|
18
|
+
}]
|
|
19
|
+
}
|
|
20
|
+
},
|
|
6
21
|
menu: "widget",
|
|
7
22
|
contents: "medialist_item+",
|
|
8
|
-
html: '<div class="ui items unstackable medialist"></div>',
|
|
23
|
+
html: '<div class="ui items unstackable medialist [size]"></div>',
|
|
9
24
|
stylesheets: [
|
|
10
|
-
'../ui/
|
|
25
|
+
'../ui/medialist.css',
|
|
11
26
|
]
|
|
12
27
|
};
|
|
13
28
|
|
package/elements/menu.js
CHANGED
package/elements/page.js
CHANGED
|
@@ -1,20 +1,16 @@
|
|
|
1
|
-
exports.page.stylesheets
|
|
2
|
-
...exports.page.stylesheets,
|
|
1
|
+
exports.page.stylesheets.push(
|
|
3
2
|
'../ui/components/reset.css',
|
|
4
3
|
'../ui/site.css',
|
|
5
4
|
'../ui/page.css',
|
|
6
5
|
'../ui/transition.css'
|
|
7
|
-
|
|
6
|
+
);
|
|
8
7
|
|
|
9
|
-
exports.page.resources =
|
|
10
|
-
|
|
11
|
-
site: '../ui/site.css'
|
|
12
|
-
};
|
|
8
|
+
exports.page.resources.reset = '../ui/components/reset.css';
|
|
9
|
+
exports.page.resources.site = '../ui/site.css';
|
|
13
10
|
|
|
14
|
-
exports.page.scripts
|
|
15
|
-
...exports.page.scripts,
|
|
11
|
+
exports.page.scripts.push(
|
|
16
12
|
'../ui/transition.js'
|
|
17
|
-
|
|
13
|
+
);
|
|
18
14
|
|
|
19
15
|
exports.page.properties.transition = {
|
|
20
16
|
title: 'Transition',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pageboard/html",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"repository": {
|
|
@@ -13,17 +13,16 @@
|
|
|
13
13
|
"url": "https://github.com/pageboard/client/issues"
|
|
14
14
|
},
|
|
15
15
|
"homepage": "https://github.com/pageboard/client#readme",
|
|
16
|
-
"dependencies": {
|
|
17
|
-
"devDependencies": {
|
|
16
|
+
"dependencies": {
|
|
18
17
|
"nouislider": "^15.8.1",
|
|
19
|
-
"postinstall": "^0.
|
|
18
|
+
"postinstall": "^0.11.0"
|
|
20
19
|
},
|
|
21
|
-
"postinstall": {
|
|
22
|
-
|
|
23
|
-
"nouislider/dist/nouislider.
|
|
24
|
-
"nouislider/dist/nouislider.css": "copy lib/"
|
|
20
|
+
"postinstall": {
|
|
21
|
+
"nouislider/dist/nouislider.js": "link lib/",
|
|
22
|
+
"nouislider/dist/nouislider.css": "link lib/"
|
|
25
23
|
},
|
|
26
24
|
"pageboard": {
|
|
25
|
+
"version": "^0.16",
|
|
27
26
|
"priority": -10,
|
|
28
27
|
"directories": [
|
|
29
28
|
"elements",
|
package/ui/consent.css
CHANGED
|
@@ -13,9 +13,16 @@ footer [block-type="consent_form"][data-transient="true"] {
|
|
|
13
13
|
[block-type="consent_form"][data-transient="true"]:not(.visible) {
|
|
14
14
|
display:none;
|
|
15
15
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
|
|
17
|
+
[block-type="consent_form"] > [block-content="content"] {
|
|
18
|
+
display:none;
|
|
19
|
+
}
|
|
20
|
+
[block-type="consent_form"] > .view {
|
|
21
|
+
position:relative;
|
|
22
|
+
}
|
|
23
|
+
[contenteditable] [block-type="consent_form"] > [block-content="content"] {
|
|
24
|
+
display:block;
|
|
25
|
+
min-height:1em;
|
|
19
26
|
}
|
|
20
27
|
|
|
21
28
|
[contenteditable] [block-focused="last"] > .form[block-type="consent_form"][data-transient="true"],
|
package/ui/consent.js
CHANGED
|
@@ -3,51 +3,67 @@ class HTMLElementConsent extends Page.create(HTMLFormElement) {
|
|
|
3
3
|
dataTransient: false
|
|
4
4
|
};
|
|
5
5
|
|
|
6
|
-
static
|
|
7
|
-
|
|
6
|
+
static explicits = new Set();
|
|
7
|
+
|
|
8
|
+
static ask(state, consent) {
|
|
8
9
|
let tacit = true;
|
|
9
|
-
|
|
10
|
+
const forms = document.querySelectorAll('[block-type="consent_form"]');
|
|
11
|
+
const consents = state.scope.storage.all();
|
|
12
|
+
for (const node of forms) {
|
|
13
|
+
window.HTMLElementForm.prototype.fill.call(node, consents);
|
|
10
14
|
node.classList.add('visible');
|
|
11
|
-
tacit = false;
|
|
15
|
+
tacit = consent && !node.querySelector(`[name="${consent}"]`) || false;
|
|
12
16
|
}
|
|
13
|
-
|
|
17
|
+
if (!tacit) this.explicits.add(consent);
|
|
18
|
+
return tacit ? "yes" : null;
|
|
14
19
|
}
|
|
15
|
-
|
|
20
|
+
paint(state) {
|
|
16
21
|
if (state.scope.$write) return;
|
|
22
|
+
this.constructor.explicits = new Set();
|
|
23
|
+
const view = this.ownView;
|
|
24
|
+
view.textContent = '';
|
|
25
|
+
const tmpl = this.ownTpl.prerender();
|
|
26
|
+
view.appendChild(tmpl.content.cloneNode(true));
|
|
27
|
+
window.HTMLElementForm.prototype.fill.call(this, state.scope.storage.all());
|
|
28
|
+
state.chain('consent', this);
|
|
29
|
+
}
|
|
30
|
+
chainConsent(state) {
|
|
17
31
|
if (this.options.transient) {
|
|
18
|
-
|
|
19
|
-
if (tmpl.content && tmpl.children.length == 0) {
|
|
20
|
-
tmpl.appendChild(tmpl.content);
|
|
21
|
-
}
|
|
32
|
+
this.classList.remove('visible');
|
|
22
33
|
}
|
|
23
|
-
state.consent(this);
|
|
24
34
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
35
|
+
handleChange(e, state) {
|
|
36
|
+
if (e.type == "submit" || !this.elements.find(item => item.type == "submit")) {
|
|
37
|
+
setTimeout(() => {
|
|
38
|
+
// let fieldset handle change first
|
|
39
|
+
this.handleSubmit(e, state);
|
|
40
|
+
}, 10);
|
|
41
|
+
}
|
|
30
42
|
}
|
|
31
43
|
handleSubmit(e, state) {
|
|
32
44
|
if (e.type == "submit") e.preventDefault();
|
|
33
45
|
if (state.scope.$write) return;
|
|
34
|
-
const
|
|
35
|
-
const
|
|
36
|
-
|
|
46
|
+
const consents = window.HTMLElementForm.prototype.read.call(this);
|
|
47
|
+
const names = new Set();
|
|
48
|
+
for (const node of this.elements) {
|
|
49
|
+
if (node.name?.startsWith('consent.')) names.add(node.name);
|
|
50
|
+
}
|
|
51
|
+
const def = consents.consent;
|
|
52
|
+
if (def != "custom") for (const consent of names) {
|
|
53
|
+
consents[consent] = def;
|
|
54
|
+
}
|
|
55
|
+
if (Array.from(names).some(c => consents[c] == null)) {
|
|
56
|
+
// not all consents have been answered
|
|
37
57
|
return;
|
|
38
58
|
}
|
|
39
|
-
|
|
40
|
-
|
|
59
|
+
for (const [key, val] of Object.entries(consents)) {
|
|
60
|
+
state.scope.storage.set(key, val);
|
|
61
|
+
}
|
|
41
62
|
state.copy().runChain('consent');
|
|
42
63
|
}
|
|
43
|
-
handleChange(e, state) {
|
|
44
|
-
this.handleSubmit(e, state);
|
|
45
|
-
}
|
|
46
64
|
patch(state) {
|
|
47
65
|
if (state.scope.$write) return;
|
|
48
|
-
|
|
49
|
-
this.ownTpl.prerender();
|
|
50
|
-
}
|
|
66
|
+
this.ownTpl.prerender();
|
|
51
67
|
}
|
|
52
68
|
get ownTpl() {
|
|
53
69
|
return this.children.find(
|
|
@@ -59,31 +75,17 @@ class HTMLElementConsent extends Page.create(HTMLFormElement) {
|
|
|
59
75
|
}
|
|
60
76
|
}
|
|
61
77
|
|
|
62
|
-
Page.constructor.prototype.consent = function (
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
this.chain('consent', fn);
|
|
68
|
-
if (consent === undefined) {
|
|
69
|
-
HTMLElementConsent.waiting = true;
|
|
70
|
-
} else if (consent === null) {
|
|
71
|
-
// setup finished but no consent is done yet, ask consent
|
|
72
|
-
this.reconsent();
|
|
78
|
+
Page.constructor.prototype.consent = function (listener, ask) {
|
|
79
|
+
const { consent } = listener.constructor;
|
|
80
|
+
if (!consent) {
|
|
81
|
+
console.warn("Expected a static consent field", listener);
|
|
82
|
+
return;
|
|
73
83
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
if (fn) this.consent(fn);
|
|
78
|
-
const consent = this.scope.$consent;
|
|
79
|
-
let asking = false;
|
|
80
|
-
if (consent != "yes") {
|
|
81
|
-
asking = HTMLElementConsent.ask();
|
|
84
|
+
const cur = this.scope.storage.get(consent);
|
|
85
|
+
if (cur == null || ask) {
|
|
86
|
+
this.scope.storage.set(consent, HTMLElementConsent.ask(this, consent));
|
|
82
87
|
}
|
|
83
|
-
|
|
84
|
-
if (consent == null) this.scope.$consent = "yes";
|
|
85
|
-
}
|
|
86
|
-
return asking;
|
|
88
|
+
this.chain('consent', listener);
|
|
87
89
|
};
|
|
88
90
|
|
|
89
91
|
Page.define(`element-consent`, HTMLElementConsent, 'form');
|
|
@@ -91,12 +93,7 @@ Page.define(`element-consent`, HTMLElementConsent, 'form');
|
|
|
91
93
|
|
|
92
94
|
Page.paint(state => {
|
|
93
95
|
state.finish(() => {
|
|
94
|
-
|
|
95
|
-
if (HTMLElementConsent.waiting) {
|
|
96
|
-
if (state.reconsent()) run = false;
|
|
97
|
-
}
|
|
98
|
-
if (run) {
|
|
99
|
-
// do not change current state stage
|
|
96
|
+
if (!HTMLElementConsent.explicits.size) {
|
|
100
97
|
state.copy().runChain('consent');
|
|
101
98
|
}
|
|
102
99
|
});
|
package/ui/embed.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
class HTMLElementEmbed extends Page.Element {
|
|
2
|
+
static consent = "consent.embed";
|
|
2
3
|
static defaults = {
|
|
3
4
|
src: null,
|
|
4
5
|
query: null,
|
|
@@ -11,7 +12,7 @@ class HTMLElementEmbed extends Page.Element {
|
|
|
11
12
|
state.consent(this);
|
|
12
13
|
}
|
|
13
14
|
get currentSrc() {
|
|
14
|
-
return this.querySelector('iframe')?.src
|
|
15
|
+
return this.querySelector('iframe')?.getAttribute('src');
|
|
15
16
|
}
|
|
16
17
|
patch(state) {
|
|
17
18
|
const { src } = this.options;
|
|
@@ -21,7 +22,7 @@ class HTMLElementEmbed extends Page.Element {
|
|
|
21
22
|
if (width && height) this.style.paddingBottom = `calc(${height} / ${width} * 100%)`;
|
|
22
23
|
}
|
|
23
24
|
consent(state) {
|
|
24
|
-
const consent = state.scope
|
|
25
|
+
const consent = state.scope.storage.get(this.constructor.consent);
|
|
25
26
|
this.classList.toggle('denied', consent == "no");
|
|
26
27
|
this.classList.toggle('waiting', consent == null);
|
|
27
28
|
|
|
@@ -57,7 +58,9 @@ class HTMLElementEmbed extends Page.Element {
|
|
|
57
58
|
}
|
|
58
59
|
}
|
|
59
60
|
captureClick(e, state) {
|
|
60
|
-
if (this.matches('.denied'))
|
|
61
|
+
if (this.matches('.denied')) {
|
|
62
|
+
state.consent(this, true);
|
|
63
|
+
}
|
|
61
64
|
}
|
|
62
65
|
captureLoad() {
|
|
63
66
|
this.classList.remove('loading');
|