apostrophe 4.30.0 → 4.31.0-alpha.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/CHANGELOG.md +67 -2
- package/claude-tools/detect-handles.js +46 -0
- package/claude-tools/minimal-hang-test.js +28 -0
- package/claude-tools/mongo-close-test.js +11 -0
- package/claude-tools/stdin-ref-test.js +14 -0
- package/eslint.config.js +3 -1
- package/modules/@apostrophecms/area/index.js +94 -2
- package/modules/@apostrophecms/area/lib/custom-tags/area.js +1 -40
- package/modules/@apostrophecms/area/ui/apos/components/AposBreadcrumbOperations.vue +0 -1
- package/modules/@apostrophecms/area/ui/apos/components/AposWidgetControls.vue +0 -1
- package/modules/@apostrophecms/attachment/index.js +4 -1
- package/modules/@apostrophecms/db/index.js +68 -27
- package/modules/@apostrophecms/doc-type/ui/apos/logic/AposDocContextMenu.js +5 -3
- package/modules/@apostrophecms/express/index.js +2 -0
- package/modules/@apostrophecms/http/index.js +1 -1
- package/modules/@apostrophecms/i18n/i18n/en.json +3 -0
- package/modules/@apostrophecms/image/ui/apos/components/AposMediaManagerEditor.vue +2 -2
- package/modules/@apostrophecms/job/index.js +9 -7
- package/modules/@apostrophecms/layout-widget/ui/apos/components/AposGridColumn.vue +0 -1
- package/modules/@apostrophecms/layout-widget/ui/apos/components/AposGridManager.vue +0 -1
- package/modules/@apostrophecms/login/ui/apos/components/TheAposLogin.vue +10 -2
- package/modules/@apostrophecms/login/ui/apos/components/TheAposLoginHeader.vue +3 -3
- package/modules/@apostrophecms/modal/ui/apos/components/AposModal.vue +52 -23
- package/modules/@apostrophecms/modal/ui/apos/components/AposModalTabs.vue +6 -1
- package/modules/@apostrophecms/oembed/index.js +2 -1
- package/modules/@apostrophecms/piece-page-type/index.js +7 -0
- package/modules/@apostrophecms/piece-type/index.js +2 -1
- package/modules/@apostrophecms/piece-type/ui/apos/components/AposDocsManagerDisplay.vue +7 -2
- package/modules/@apostrophecms/recently-edited/ui/apos/components/AposCellTitle.vue +1 -0
- package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposRichTextWidgetEditor.vue +21 -4
- package/modules/@apostrophecms/schema/ui/apos/components/AposArrayEditor.vue +1 -0
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputDateAndTime.vue +7 -2
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputSelect.vue +1 -0
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputWrapper.vue +1 -1
- package/modules/@apostrophecms/schema/ui/apos/components/AposSubform.vue +1 -0
- package/modules/@apostrophecms/schema/ui/apos/logic/AposSubform.js +10 -0
- package/modules/@apostrophecms/styles/ui/apos/components/TheAposStyles.vue +1 -0
- package/modules/@apostrophecms/template/index.js +117 -11
- package/modules/@apostrophecms/template/lib/jsxLoader.js +128 -0
- package/modules/@apostrophecms/template/lib/jsxRender.js +490 -0
- package/modules/@apostrophecms/template/lib/jsxRuntime.js +276 -0
- package/modules/@apostrophecms/template/lib/nunjucksLoader.js +11 -36
- package/modules/@apostrophecms/template/lib/viewWatcher.js +113 -0
- package/modules/@apostrophecms/ui/ui/apos/components/AposButtonGroup.vue +1 -1
- package/modules/@apostrophecms/ui/ui/apos/components/AposCellLastEdited.vue +1 -1
- package/modules/@apostrophecms/ui/ui/apos/components/AposSelect.vue +1 -0
- package/modules/@apostrophecms/ui/ui/apos/components/AposSlat.vue +10 -4
- package/modules/@apostrophecms/ui/ui/apos/components/AposSlatList.vue +6 -1
- package/modules/@apostrophecms/ui/ui/apos/components/AposSubformPreview.vue +1 -1
- package/modules/@apostrophecms/ui/ui/apos/components/AposTreeHeader.vue +1 -1
- package/modules/@apostrophecms/ui/ui/apos/scss/global/_theme.scss +1 -0
- package/modules/@apostrophecms/uploadfs/index.js +3 -0
- package/modules/@apostrophecms/util/index.js +3 -3
- package/package.json +14 -10
- package/test/add-missing-schema-fields-project/test.js +22 -3
- package/test/assets.js +110 -67
- package/test/db-tools.js +365 -0
- package/test/db.js +24 -15
- package/test/default-adapter.js +256 -0
- package/test/external-front.js +419 -1
- package/test/job.js +1 -1
- package/test/modules/jsx-area-test/index.js +23 -0
- package/test/modules/jsx-area-test/views/bad-area.jsx +7 -0
- package/test/modules/jsx-area-test/views/with-area-ctx.jsx +13 -0
- package/test/modules/jsx-area-test/views/with-area.jsx +7 -0
- package/test/modules/jsx-area-test/views/with-widget-ctx.jsx +12 -0
- package/test/modules/jsx-area-test/views/with-widget.jsx +7 -0
- package/test/modules/jsx-async-widget/index.js +6 -0
- package/test/modules/jsx-async-widget/views/widget.jsx +11 -0
- package/test/modules/jsx-bridge-test/index.js +1 -0
- package/test/modules/jsx-bridge-test/views/cross-module.jsx +7 -0
- package/test/modules/jsx-bridge-test/views/disambig-name-only.jsx +7 -0
- package/test/modules/jsx-bridge-test/views/disambig-target.jsx +8 -0
- package/test/modules/jsx-bridge-test/views/disambig-with-template-name.jsx +7 -0
- package/test/modules/jsx-bridge-test/views/include-html.jsx +7 -0
- package/test/modules/jsx-bridge-test/views/include-target.html +4 -0
- package/test/modules/jsx-bridge-test/views/jsx-extends-via-extend.jsx +9 -0
- package/test/modules/jsx-bridge-test/views/jsx-extends.jsx +9 -0
- package/test/modules/jsx-bridge-test/views/jsx-layout.jsx +14 -0
- package/test/modules/jsx-bridge-test/views/njk-extends.jsx +14 -0
- package/test/modules/jsx-bridge-test/views/njk-layout.html +9 -0
- package/test/modules/jsx-bridge-test/views/short-form.jsx +7 -0
- package/test/modules/jsx-bridge-test/views/short-target.jsx +3 -0
- package/test/modules/jsx-component-test/index.js +15 -0
- package/test/modules/jsx-component-test/views/greet.html +1 -0
- package/test/modules/jsx-component-test/views/uses-component.jsx +8 -0
- package/test/modules/jsx-ctx-widget/index.js +6 -0
- package/test/modules/jsx-ctx-widget/views/widget.jsx +4 -0
- package/test/modules/jsx-mixed-test/index.js +9 -0
- package/test/modules/jsx-mixed-test/views/apos-full.jsx +21 -0
- package/test/modules/jsx-mixed-test/views/async-list.jsx +12 -0
- package/test/modules/jsx-mixed-test/views/lib/format.js +3 -0
- package/test/modules/jsx-mixed-test/views/localized.jsx +3 -0
- package/test/modules/jsx-mixed-test/views/partial.jsx +3 -0
- package/test/modules/jsx-mixed-test/views/safe-helper.jsx +3 -0
- package/test/modules/jsx-mixed-test/views/syntax-error.jsx +3 -0
- package/test/modules/jsx-mixed-test/views/throws.jsx +5 -0
- package/test/modules/jsx-mixed-test/views/uses-import.jsx +5 -0
- package/test/modules/jsx-mixed-test/views/uses-require.jsx +5 -0
- package/test/modules/jsx-watcher-cross-test/index.js +5 -0
- package/test/modules/jsx-watcher-cross-test/views/cross-template.jsx +3 -0
- package/test/modules/jsx-watcher-test/index.js +5 -0
- package/test/modules/jsx-watcher-test/views/watcher-test.jsx +3 -0
- package/test/modules/template-jsx-options-test/index.js +12 -0
- package/test/modules/template-jsx-options-test/views/options-test.jsx +9 -0
- package/test/modules/template-jsx-subclass-test/index.js +3 -0
- package/test/modules/template-jsx-subclass-test/views/override-test.jsx +3 -0
- package/test/modules/template-jsx-test/index.js +9 -0
- package/test/modules/template-jsx-test/views/boolean-attrs.jsx +11 -0
- package/test/modules/template-jsx-test/views/class-and-for.jsx +7 -0
- package/test/modules/template-jsx-test/views/dangerously-set.jsx +3 -0
- package/test/modules/template-jsx-test/views/escape-attr.jsx +3 -0
- package/test/modules/template-jsx-test/views/escape-body.jsx +3 -0
- package/test/modules/template-jsx-test/views/inherit-test.jsx +3 -0
- package/test/modules/template-jsx-test/views/list.jsx +7 -0
- package/test/modules/template-jsx-test/views/override-test.jsx +3 -0
- package/test/modules/template-jsx-test/views/svg-attrs.jsx +27 -0
- package/test/modules/template-jsx-test/views/test.jsx +3 -0
- package/test/modules/template-jsx-test/views/void-elements.jsx +9 -0
- package/test/templates-jsx-watcher.js +135 -0
- package/test/templates-jsx.js +537 -0
- package/test-lib/util.js +50 -14
- package/.claude/settings.local.json +0 -15
- package/lib/mongodb-connect.js +0 -62
- package/test/add-missing-schema-fields-project/node_modules/.package-lock.json +0 -131
|
@@ -244,7 +244,9 @@ module.exports = {
|
|
|
244
244
|
},
|
|
245
245
|
setTotal (n) {
|
|
246
246
|
total = n;
|
|
247
|
-
|
|
247
|
+
const result = self.setTotal(job, n);
|
|
248
|
+
promises.push(result);
|
|
249
|
+
return result;
|
|
248
250
|
},
|
|
249
251
|
setResults (_results) {
|
|
250
252
|
results = _results;
|
|
@@ -412,12 +414,12 @@ module.exports = {
|
|
|
412
414
|
//
|
|
413
415
|
// No promise is returned as this method just updates
|
|
414
416
|
// the job tracking information in the background.
|
|
415
|
-
setTotal(job, total) {
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
}
|
|
417
|
+
async setTotal(job, total) {
|
|
418
|
+
try {
|
|
419
|
+
await self.db.updateOne({ _id: job._id }, { $set: { total } });
|
|
420
|
+
} catch (err) {
|
|
421
|
+
self.apos.util.error(err);
|
|
422
|
+
}
|
|
421
423
|
},
|
|
422
424
|
// Mark the given job as ended. If `success`
|
|
423
425
|
// is true the job is reported as an overall
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
<div
|
|
11
11
|
v-if="showNav"
|
|
12
12
|
class="apos-login__nav"
|
|
13
|
+
role="navigation"
|
|
13
14
|
>
|
|
14
15
|
<a
|
|
15
16
|
href="#"
|
|
@@ -22,7 +23,13 @@
|
|
|
22
23
|
>{{ $t('apostrophe:loginHome') }}</a>
|
|
23
24
|
</div>
|
|
24
25
|
</transition>
|
|
25
|
-
<div
|
|
26
|
+
<div
|
|
27
|
+
class="apos-login__wrapper"
|
|
28
|
+
role="main"
|
|
29
|
+
>
|
|
30
|
+
<h1 class="apos-sr-only">
|
|
31
|
+
{{ $t('apostrophe:login') }}
|
|
32
|
+
</h1>
|
|
26
33
|
<transition
|
|
27
34
|
name="fade-body"
|
|
28
35
|
mode="out-in"
|
|
@@ -55,6 +62,7 @@
|
|
|
55
62
|
<div
|
|
56
63
|
v-show="loaded"
|
|
57
64
|
class="apos-login__footer"
|
|
65
|
+
role="contentinfo"
|
|
58
66
|
>
|
|
59
67
|
<AposLogo class="apos-login__logo" />
|
|
60
68
|
<label
|
|
@@ -234,7 +242,7 @@ export default {
|
|
|
234
242
|
overflow: hidden;
|
|
235
243
|
margin-right: 0;
|
|
236
244
|
margin-left: auto;
|
|
237
|
-
color: var(--a-base-
|
|
245
|
+
color: var(--a-base-2);
|
|
238
246
|
text-overflow: clip;
|
|
239
247
|
white-space: nowrap;
|
|
240
248
|
}
|
|
@@ -112,16 +112,16 @@ export default {
|
|
|
112
112
|
text-transform: capitalize;
|
|
113
113
|
padding: 6px 12px;
|
|
114
114
|
color: var(--a-white);
|
|
115
|
-
background: var(--a-success);
|
|
115
|
+
background: var(--a-success-dark);
|
|
116
116
|
border-radius: 5px;
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
&--development {
|
|
120
|
-
background: var(--a-danger);
|
|
120
|
+
background: var(--a-danger-button-hover);
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
&--success, &--staging {
|
|
124
|
-
background: var(--a-warning);
|
|
124
|
+
background: var(--a-warning-dark);
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
127
|
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
:data-apos-graph-key="props.graphKey || undefined"
|
|
17
17
|
tabindex="0"
|
|
18
18
|
@focus.capture="captureFocus"
|
|
19
|
-
@
|
|
19
|
+
@keydown.tab="onKeydownTab"
|
|
20
20
|
@keyup.esc="onKeyup"
|
|
21
21
|
>
|
|
22
22
|
<transition :name="transitionType">
|
|
@@ -67,6 +67,7 @@
|
|
|
67
67
|
<header
|
|
68
68
|
v-if="!modal.disableHeader"
|
|
69
69
|
class="apos-modal__header"
|
|
70
|
+
role="none"
|
|
70
71
|
>
|
|
71
72
|
<div class="apos-modal__header__main">
|
|
72
73
|
<div
|
|
@@ -133,6 +134,7 @@
|
|
|
133
134
|
<footer
|
|
134
135
|
v-if="hasSlot('footer')"
|
|
135
136
|
class="apos-modal__footer"
|
|
137
|
+
role="none"
|
|
136
138
|
>
|
|
137
139
|
<div class="apos-modal__footer__inner">
|
|
138
140
|
<slot name="footer" />
|
|
@@ -216,6 +218,22 @@ const nonDraggableElements = [
|
|
|
216
218
|
'.apos-input-array-inline-table'
|
|
217
219
|
];
|
|
218
220
|
|
|
221
|
+
// Selector for focusable elements inside the modal. Used both at trap setup
|
|
222
|
+
// and on every Tab keydown to refresh the cycle list, so that elements that
|
|
223
|
+
// became disabled/hidden (e.g. Save when validation fails) or newly visible
|
|
224
|
+
// are reflected.
|
|
225
|
+
const focusableSelector = [
|
|
226
|
+
'[tabindex]',
|
|
227
|
+
'[href]',
|
|
228
|
+
'input',
|
|
229
|
+
'select',
|
|
230
|
+
'textarea',
|
|
231
|
+
'button',
|
|
232
|
+
'[data-apos-focus-priority]'
|
|
233
|
+
]
|
|
234
|
+
.map(s => `${s}:not([tabindex="-1"]):not([disabled]):not([type="hidden"]):not([aria-hidden]):not(.apos-sr-only)`)
|
|
235
|
+
.join(', ');
|
|
236
|
+
|
|
219
237
|
const resizeSides = [
|
|
220
238
|
{
|
|
221
239
|
edge: 'top',
|
|
@@ -476,13 +494,35 @@ onUnmounted(() => {
|
|
|
476
494
|
}
|
|
477
495
|
});
|
|
478
496
|
|
|
479
|
-
|
|
497
|
+
// Handle Tab on keydown — before the browser moves focus.
|
|
498
|
+
// Handling Tab on keyup is too late: the browser has already moved focus,
|
|
499
|
+
// so the cycling logic sees the wrong activeElement.
|
|
500
|
+
//
|
|
501
|
+
// We also recompute the focusable list here on every Tab, scoped to
|
|
502
|
+
// modalEl, instead of relying on the snapshot taken at trapFocus() time.
|
|
503
|
+
function onKeydownTab(event) {
|
|
504
|
+
if (!shouldTrapFocus.value) {
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
480
507
|
if (!store.isOnTop(modalEl.value)) {
|
|
481
508
|
return;
|
|
482
509
|
}
|
|
510
|
+
if (event.target?.nodeName?.toLowerCase() === 'textarea') {
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
// Skip visually hidden elements when cycling — but only here, not in
|
|
514
|
+
// trapFocus. Initial focus runs while `renderingElements` is still true,
|
|
515
|
+
// which puts the content under display:none and makes every candidate's
|
|
516
|
+
// offsetParent null.
|
|
517
|
+
const elements = getFocusableElements(modalEl.value)
|
|
518
|
+
.filter(el => el.offsetParent !== null);
|
|
519
|
+
// Keep the store snapshot consistent for other consumers.
|
|
520
|
+
store.updateModalData(props.modalData.id, { elementsToFocus: elements });
|
|
521
|
+
cycleElementsToFocus(event, elements);
|
|
522
|
+
}
|
|
483
523
|
|
|
484
|
-
|
|
485
|
-
|
|
524
|
+
function onKeyup(event) {
|
|
525
|
+
if (!store.isOnTop(modalEl.value)) {
|
|
486
526
|
return;
|
|
487
527
|
}
|
|
488
528
|
|
|
@@ -517,23 +557,16 @@ function captureFocus(e) {
|
|
|
517
557
|
store.updateModalData(props.modalData.id, { focusedElement: e.target });
|
|
518
558
|
}
|
|
519
559
|
|
|
560
|
+
function getFocusableElements(rootEl) {
|
|
561
|
+
if (!rootEl) {
|
|
562
|
+
return [];
|
|
563
|
+
}
|
|
564
|
+
return [ ...rootEl.querySelectorAll(focusableSelector) ];
|
|
565
|
+
}
|
|
566
|
+
|
|
520
567
|
async function trapFocus() {
|
|
521
568
|
if (modalEl?.value) {
|
|
522
|
-
const
|
|
523
|
-
'[tabindex]',
|
|
524
|
-
'[href]',
|
|
525
|
-
'input',
|
|
526
|
-
'select',
|
|
527
|
-
'textarea',
|
|
528
|
-
'button',
|
|
529
|
-
'[data-apos-focus-priority]'
|
|
530
|
-
];
|
|
531
|
-
|
|
532
|
-
const selector = elementSelectors
|
|
533
|
-
.map(addExcludingAttributes)
|
|
534
|
-
.join(', ');
|
|
535
|
-
|
|
536
|
-
const elementsToFocus = [ ...modalEl.value.querySelectorAll(selector) ];
|
|
569
|
+
const elementsToFocus = getFocusableElements(modalEl.value);
|
|
537
570
|
|
|
538
571
|
store.updateModalData(props.modalData.id, { elementsToFocus });
|
|
539
572
|
|
|
@@ -556,10 +589,6 @@ async function trapFocus() {
|
|
|
556
589
|
await nextTick();
|
|
557
590
|
focusElement(props.modalData.focusedElement, firstElementToFocus);
|
|
558
591
|
}
|
|
559
|
-
|
|
560
|
-
function addExcludingAttributes(element) {
|
|
561
|
-
return `${element}:not([tabindex="-1"]):not([disabled]):not([type="hidden"]):not([aria-hidden]):not(.apos-sr-only)`;
|
|
562
|
-
}
|
|
563
592
|
}
|
|
564
593
|
|
|
565
594
|
function close() {
|
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="apos-modal-tabs">
|
|
3
|
-
<ul
|
|
3
|
+
<ul
|
|
4
|
+
class="apos-modal-tabs__tabs"
|
|
5
|
+
role="tablist"
|
|
6
|
+
>
|
|
4
7
|
<li
|
|
5
8
|
v-for="tab in tabs"
|
|
6
9
|
v-show="tab.isVisible !== false"
|
|
7
10
|
:key="tab.name"
|
|
8
11
|
class="apos-modal-tabs__tab"
|
|
12
|
+
role="presentation"
|
|
9
13
|
>
|
|
10
14
|
<button
|
|
11
15
|
:id="tab.name"
|
|
12
16
|
class="apos-modal-tabs__btn"
|
|
17
|
+
role="tab"
|
|
13
18
|
:aria-selected="tab.name === current ? true : false"
|
|
14
19
|
@click="selectTab"
|
|
15
20
|
>
|
|
@@ -54,7 +54,8 @@ module.exports = {
|
|
|
54
54
|
|
|
55
55
|
self.oembetter.allowlist(minimumAllowlist.concat(self.options.allowlist || []));
|
|
56
56
|
|
|
57
|
-
const minimumEndpoints = self.options.minimumEndpoints ||
|
|
57
|
+
const minimumEndpoints = self.options.minimumEndpoints ||
|
|
58
|
+
self.oembetter.suggestedEndpoints;
|
|
58
59
|
self.oembetter.endpoints(
|
|
59
60
|
minimumEndpoints.concat(self.options.endpoints || [])
|
|
60
61
|
);
|
|
@@ -427,7 +427,14 @@ module.exports = {
|
|
|
427
427
|
return metadata;
|
|
428
428
|
}
|
|
429
429
|
const [ pm ] = metadata;
|
|
430
|
+
// indexQuery is designed to be called with the
|
|
431
|
+
// index page in question as req.data.page. To
|
|
432
|
+
// reuse it for URL metadata purposes we must
|
|
433
|
+
// meet that expectation
|
|
434
|
+
const pageWas = req.data.page;
|
|
435
|
+
req.data.page = doc;
|
|
430
436
|
const query = self.indexQuery(req);
|
|
437
|
+
req.data.page = pageWas;
|
|
431
438
|
const filters = await self.getFiltersWithChoices(query, { allCounts: true });
|
|
432
439
|
|
|
433
440
|
// 1. Enumerate every filter + choice combination
|
|
@@ -4,8 +4,11 @@
|
|
|
4
4
|
<tr>
|
|
5
5
|
<th
|
|
6
6
|
v-if="hasBatchOperations"
|
|
7
|
+
scope="col"
|
|
7
8
|
class="apos-table__header"
|
|
8
|
-
|
|
9
|
+
>
|
|
10
|
+
<span class="apos-sr-only">{{ $t('apostrophe:selectAll') }}</span>
|
|
11
|
+
</th>
|
|
9
12
|
<th
|
|
10
13
|
v-for="header in headers"
|
|
11
14
|
:key="header.label"
|
|
@@ -16,6 +19,7 @@
|
|
|
16
19
|
<component
|
|
17
20
|
:is="getEl(header)"
|
|
18
21
|
class="apos-table__header-label"
|
|
22
|
+
:class="{ 'apos-sr-only': header.labelSrOnly }"
|
|
19
23
|
>
|
|
20
24
|
<component
|
|
21
25
|
:is="icons[header.labelIcon]"
|
|
@@ -28,11 +32,12 @@
|
|
|
28
32
|
</th>
|
|
29
33
|
<th
|
|
30
34
|
key="contextMenu"
|
|
35
|
+
scope="col"
|
|
31
36
|
class="apos-table__header"
|
|
32
37
|
>
|
|
33
38
|
<component
|
|
34
39
|
:is="getEl({})"
|
|
35
|
-
class="apos-table__header-label apos-
|
|
40
|
+
class="apos-table__header-label apos-sr-only"
|
|
36
41
|
>
|
|
37
42
|
{{ $t('apostrophe:moreOperations') }}
|
|
38
43
|
</component>
|
package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposRichTextWidgetEditor.vue
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
3
|
:id="widgetId"
|
|
4
|
-
:aria-controls="`insert-menu-${modelValue._id}`"
|
|
5
4
|
:style="widgetStyles.inline"
|
|
6
5
|
:class="widgetStyles.classes"
|
|
7
6
|
@keyup="handleUIKeyup"
|
|
@@ -43,7 +42,12 @@
|
|
|
43
42
|
ref="insertMenu"
|
|
44
43
|
plugin-key="insertMenu"
|
|
45
44
|
:class="insertMenuClasses"
|
|
46
|
-
:tippy-options="{
|
|
45
|
+
:tippy-options="{
|
|
46
|
+
duration: 100,
|
|
47
|
+
zIndex: 999,
|
|
48
|
+
placement: 'bottom-start',
|
|
49
|
+
aria: { content: null, expanded: false }
|
|
50
|
+
}"
|
|
47
51
|
:should-show="showFloatingMenu"
|
|
48
52
|
:editor="editor"
|
|
49
53
|
role="listbox"
|
|
@@ -229,7 +233,11 @@ export default {
|
|
|
229
233
|
inertia: true,
|
|
230
234
|
placement: 'bottom',
|
|
231
235
|
hideOnClick: false,
|
|
232
|
-
onHide: this.onBubbleHide
|
|
236
|
+
onHide: this.onBubbleHide,
|
|
237
|
+
aria: {
|
|
238
|
+
content: null,
|
|
239
|
+
expanded: false
|
|
240
|
+
}
|
|
233
241
|
};
|
|
234
242
|
},
|
|
235
243
|
// Note that context menu class-list expects a string
|
|
@@ -264,7 +272,11 @@ export default {
|
|
|
264
272
|
placement: 'top',
|
|
265
273
|
offset: [ 0, 35 ],
|
|
266
274
|
moveTransition: 'transform 0s ease-out',
|
|
267
|
-
appendTo: document.body
|
|
275
|
+
appendTo: document.body,
|
|
276
|
+
aria: {
|
|
277
|
+
content: null,
|
|
278
|
+
expanded: false
|
|
279
|
+
}
|
|
268
280
|
};
|
|
269
281
|
},
|
|
270
282
|
moduleOptions() {
|
|
@@ -468,6 +480,11 @@ export default {
|
|
|
468
480
|
autofocus: this.autofocus,
|
|
469
481
|
onUpdate: this.editorUpdate,
|
|
470
482
|
extensions,
|
|
483
|
+
editorProps: {
|
|
484
|
+
attributes: {
|
|
485
|
+
'aria-label': this.$t('apostrophe:richTextEditor')
|
|
486
|
+
}
|
|
487
|
+
},
|
|
471
488
|
|
|
472
489
|
// The following events are triggered:
|
|
473
490
|
// - before the placeholder configuration function, when loading the page
|
|
@@ -15,13 +15,17 @@
|
|
|
15
15
|
@toggle="toggle"
|
|
16
16
|
/>
|
|
17
17
|
<input
|
|
18
|
+
:id="uid"
|
|
18
19
|
v-model="date"
|
|
19
20
|
class="apos-input apos-input--date"
|
|
20
21
|
:class="classes"
|
|
21
22
|
type="date"
|
|
22
23
|
@change="setDateAndTime"
|
|
23
24
|
>
|
|
24
|
-
<span
|
|
25
|
+
<span
|
|
26
|
+
:id="`${uid}-at`"
|
|
27
|
+
class="apos-input--label"
|
|
28
|
+
>
|
|
25
29
|
{{ $t('apostrophe:at') }}
|
|
26
30
|
</span>
|
|
27
31
|
<input
|
|
@@ -29,6 +33,7 @@
|
|
|
29
33
|
class="apos-input apos-input--time"
|
|
30
34
|
:class="classes"
|
|
31
35
|
type="time"
|
|
36
|
+
:aria-labelledby="`${uid} ${uid}-at`"
|
|
32
37
|
@change="setDateAndTime"
|
|
33
38
|
>
|
|
34
39
|
</div>
|
|
@@ -60,7 +65,7 @@ export default {
|
|
|
60
65
|
&--disabled {
|
|
61
66
|
background-color: var(--a-white);
|
|
62
67
|
border-color: var(--a-base-8);
|
|
63
|
-
color: var(--a-base-
|
|
68
|
+
color: var(--a-base-2);
|
|
64
69
|
}
|
|
65
70
|
|
|
66
71
|
&--label {
|
|
@@ -67,6 +67,16 @@ export default {
|
|
|
67
67
|
},
|
|
68
68
|
serverError() {
|
|
69
69
|
return this.error || !!this.serverErrors;
|
|
70
|
+
},
|
|
71
|
+
subformLabel() {
|
|
72
|
+
return this.$t(
|
|
73
|
+
this.subform.label ||
|
|
74
|
+
this.subform.schema?.[0]?.label ||
|
|
75
|
+
'apostrophe:notAvailable'
|
|
76
|
+
);
|
|
77
|
+
},
|
|
78
|
+
editSubformLabel() {
|
|
79
|
+
return this.$t('apostrophe:editSubform', { label: this.subformLabel });
|
|
70
80
|
}
|
|
71
81
|
},
|
|
72
82
|
|