apostrophe 4.1.0 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +42 -1
- package/lib/mongodb-connect.js +1 -1
- package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposAdminBarMenu.vue +1 -0
- package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposContextBar.vue +22 -16
- package/modules/@apostrophecms/area/index.js +1 -1
- package/modules/@apostrophecms/area/ui/apos/components/AposAreaEditor.vue +6 -1
- package/modules/@apostrophecms/db/index.js +0 -6
- package/modules/@apostrophecms/doc/index.js +19 -31
- package/modules/@apostrophecms/doc/lib/migrations.js +59 -0
- package/modules/@apostrophecms/doc-type/index.js +5 -2
- package/modules/@apostrophecms/express/index.js +3 -2
- package/modules/@apostrophecms/i18n/i18n/de.json +5 -1
- package/modules/@apostrophecms/i18n/i18n/en.json +5 -1
- package/modules/@apostrophecms/i18n/i18n/es.json +5 -1
- package/modules/@apostrophecms/i18n/i18n/fr.json +5 -1
- package/modules/@apostrophecms/i18n/i18n/it.json +5 -1
- package/modules/@apostrophecms/i18n/i18n/pt-BR.json +5 -1
- package/modules/@apostrophecms/i18n/i18n/sk.json +5 -1
- package/modules/@apostrophecms/i18n/index.js +1 -1
- package/modules/@apostrophecms/migration/index.js +5 -0
- package/modules/@apostrophecms/modal/ui/apos/apps/AposModals.js +2 -2
- package/modules/@apostrophecms/modal/ui/apos/components/AposModal.vue +188 -187
- package/modules/@apostrophecms/modal/ui/apos/composables/AposFocus.js +2 -2
- package/modules/@apostrophecms/notification/index.js +2 -0
- package/modules/@apostrophecms/piece-type/ui/apos/components/AposDocsManager.vue +2 -2
- package/modules/@apostrophecms/rich-text-widget/index.js +19 -8
- package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposRichTextWidgetEditor.vue +49 -16
- package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposTiptapMarks.vue +226 -0
- package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposTiptapStyles.vue +90 -18
- package/modules/@apostrophecms/rich-text-widget/ui/apos/tiptap-extensions/Classes.js +70 -6
- package/modules/@apostrophecms/rich-text-widget/ui/apos/tiptap-extensions/Default.js +2 -1
- package/modules/@apostrophecms/rich-text-widget/ui/apos/tiptap-extensions/Document.js +1 -1
- package/modules/@apostrophecms/rich-text-widget/ui/apos/tiptap-extensions/Heading.js +1 -1
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputColor.vue +1 -1
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputWrapper.vue +1 -1
- package/modules/@apostrophecms/schema/ui/apos/logic/AposInputColor.js +4 -0
- package/modules/@apostrophecms/schema/ui/apos/logic/AposInputSlug.js +3 -0
- package/modules/@apostrophecms/ui/ui/apos/components/AposButtonSplit.vue +2 -2
- package/modules/@apostrophecms/ui/ui/apos/lib/i18next.js +4 -8
- package/modules/@apostrophecms/user/index.js +40 -14
- package/modules/@apostrophecms/user/lib/password-hash.js +122 -0
- package/modules/@apostrophecms/util/ui/src/http.js +7 -0
- package/package.json +3 -5
- package/test/docs.js +151 -0
- package/test/password-hash.js +56 -0
- package/test/users.js +19 -3
- package/.github/workflows/outdated-dependencies.yml +0 -43
- package/modules/@apostrophecms/modal/ui/apos/mixins/AposFocusMixin.js +0 -91
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,46 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 4.2.0 (2024-04-18)
|
|
4
|
+
|
|
5
|
+
* Typing a `/` in the title field of a page no longer confuses the slug field. Thanks to [Gauav Kumar](https://github.com/gkumar9891).
|
|
6
|
+
|
|
7
|
+
### Changes
|
|
8
|
+
|
|
9
|
+
* Rich text styles are now split into Nodes and Marks, with independent toolbar controls for a better user experience when applying text styles.
|
|
10
|
+
There is no change in how the `styles` option is configured.
|
|
11
|
+
* Rich text style labels are fully localized.
|
|
12
|
+
* `i18n` module now uses the regular `req.redirect` instead of a direct `res.redirect` to ensure redirection, enabling more possibilities for `@apostrophecms/redirect` module
|
|
13
|
+
* Refactors `AposModal` component with composition api to get rid of duplicated code in `AposFocusMixin` and `AposFocus`.
|
|
14
|
+
* `APOS_MONGODB_LOG_LEVEL` has been removed. According to [mongodb documentation](https://github.com/mongodb/node-mongodb-native/blob/main/etc/notes/CHANGES_5.0.0.md#mongoclientoptionslogger-and-mongoclientoptionsloglevel-removed) "Both the logger and the logLevel options had no effect and have been removed."
|
|
15
|
+
* Update `connect-mongo` to `5.x`. Add `@apostrophecms/emulate-mongo-3-driver` dependency to keep supporting `mongodb@3.x` queries while using `mongodb@6.x`.
|
|
16
|
+
|
|
17
|
+
### Fixes
|
|
18
|
+
|
|
19
|
+
* Updates the docs `beforeInsert` handler to avoid ending with different modes being set between `_id`, `aposLocale` and `aposMode`.
|
|
20
|
+
* Adds a migration to fix potential corrupted data having different modes set between `_id`, `aposLocale` and `aposMode`.
|
|
21
|
+
* Fix a crash in `notification` when `req.body` was not present. Thanks to Michelin for contributing this fix.
|
|
22
|
+
* Addresses a console error observed when opening and closing the `@apostrophecms-pro/palette` module across various projects.
|
|
23
|
+
* Fixes the color picker field in `@apostrophecms-pro/palette` module.
|
|
24
|
+
* Ensures that the `data-apos-test` attribute in the admin bar's tray item buttons is set by passing the `action` prop to `AposButton`.
|
|
25
|
+
* Prevents stripping of query parameters from the URL when the page is either switched to edit mode or reloaded while in edit mode.
|
|
26
|
+
* Add the missing `metaType` property to newly inserted widgets.
|
|
27
|
+
|
|
28
|
+
### Security
|
|
29
|
+
|
|
30
|
+
* New passwords are now hashed with `scrypt`, the best password hash available in the Node.js core `crypto` module, following guidance from [OWASP](https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html).
|
|
31
|
+
This reduces login time while improving overall security.
|
|
32
|
+
* Old passwords are automatically re-hashed with `scrypt` on the next successful login attempt, which
|
|
33
|
+
adds some delay to that next attempt, but speeds them up forever after compared to the old implementation.
|
|
34
|
+
* Custom `scrypt` parameters for password hashing can be passed to the `@apostrophecms/user` module via the `scrypt` option. See the [Node.js documentation for `scrypt`]. Note that the `maxmem` parameter is computed automatically based on the other parameters.
|
|
35
|
+
|
|
36
|
+
## 4.1.1 (2024-03-21)
|
|
37
|
+
|
|
38
|
+
### Fixes
|
|
39
|
+
|
|
40
|
+
* Hotfix for a bug that broke the rich text editor when the rich text widget has
|
|
41
|
+
a `styles` property. The bug was introduced in 4.0.0 as an indirect side effect of deeper
|
|
42
|
+
watching behavior by Vue 3.
|
|
43
|
+
|
|
3
44
|
## 4.1.0 (2024-03-20)
|
|
4
45
|
|
|
5
46
|
### Fixes
|
|
@@ -21,7 +62,7 @@ actually exists before calling `attachment.url` still lies with the developer.
|
|
|
21
62
|
## 4.0.0 (2024-03-12)
|
|
22
63
|
|
|
23
64
|
### Adds
|
|
24
|
-
|
|
65
|
+
* Add Marks tool to the Rich Text widget for handling toggling marks.
|
|
25
66
|
* Add translation keys used by the multisite assembly module.
|
|
26
67
|
* Add side by side comparison support in AposSchema component.
|
|
27
68
|
* Add `beforeLocalize` and `afterLocalize` events.
|
package/lib/mongodb-connect.js
CHANGED
|
@@ -383,6 +383,10 @@ export default {
|
|
|
383
383
|
mode = mode || this.draftMode;
|
|
384
384
|
locale = locale || apos.i18n.locale;
|
|
385
385
|
doc = doc || this.context;
|
|
386
|
+
if (!doc) {
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
|
|
386
390
|
if ((mode === this.draftMode) && (locale === apos.i18n.locale)) {
|
|
387
391
|
if ((this.context._id === doc._id) && (!this.urlDiffers(doc._url))) {
|
|
388
392
|
return;
|
|
@@ -545,6 +549,7 @@ export default {
|
|
|
545
549
|
|
|
546
550
|
if (this.urlDiffers(doc._url)) {
|
|
547
551
|
// Slug changed, change browser URL to reflect the actual url of the doc
|
|
552
|
+
doc._url = doc._url + (window.location.search || '');
|
|
548
553
|
history.replaceState(null, '', doc._url);
|
|
549
554
|
}
|
|
550
555
|
|
|
@@ -557,17 +562,17 @@ export default {
|
|
|
557
562
|
} : {})
|
|
558
563
|
};
|
|
559
564
|
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
565
|
+
if (doc._url) {
|
|
566
|
+
refreshable.innerHTML = await apos.http.get(doc._url, {
|
|
567
|
+
qs,
|
|
568
|
+
headers: {
|
|
569
|
+
'Cache-Control': 'no-cache'
|
|
570
|
+
},
|
|
571
|
+
draft: true,
|
|
572
|
+
busy: true,
|
|
573
|
+
prefix: false
|
|
574
|
+
});
|
|
575
|
+
}
|
|
571
576
|
|
|
572
577
|
if (this.editMode && (!this.original)) {
|
|
573
578
|
// the first time we enter edit mode on the page, we need to
|
|
@@ -691,13 +696,14 @@ export default {
|
|
|
691
696
|
}
|
|
692
697
|
},
|
|
693
698
|
urlDiffers(url) {
|
|
694
|
-
|
|
695
|
-
url = url.replace(/^https?:\/\/.*?\//, '/');
|
|
696
|
-
if (url === (window.location.pathname + (window.location.search || ''))) {
|
|
699
|
+
if (!url) {
|
|
697
700
|
return false;
|
|
698
|
-
} else {
|
|
699
|
-
return true;
|
|
700
701
|
}
|
|
702
|
+
|
|
703
|
+
const normalizedUrl = url.replace(/^https?:\/\/[^/]+\//, '/');
|
|
704
|
+
const currentPageUrl = window.location.pathname + window.location.search;
|
|
705
|
+
|
|
706
|
+
return normalizedUrl !== currentPageUrl;
|
|
701
707
|
},
|
|
702
708
|
lockNotAvailable() {
|
|
703
709
|
if (this.contextStack.length) {
|
|
@@ -622,7 +622,7 @@ module.exports = {
|
|
|
622
622
|
widgetIsContextual[name] = manager.options.contextual;
|
|
623
623
|
widgetHasPlaceholder[name] = manager.options.placeholder;
|
|
624
624
|
widgetHasInitialModal[name] = !manager.options.placeholder && manager.options.initialModal !== false;
|
|
625
|
-
contextualWidgetDefaultData[name] = manager.options.defaultData;
|
|
625
|
+
contextualWidgetDefaultData[name] = manager.options.defaultData || {};
|
|
626
626
|
});
|
|
627
627
|
|
|
628
628
|
return {
|
|
@@ -429,7 +429,9 @@ export default {
|
|
|
429
429
|
},
|
|
430
430
|
async update(widget) {
|
|
431
431
|
widget.aposPlaceholder = false;
|
|
432
|
-
|
|
432
|
+
if (!widget.metaType) {
|
|
433
|
+
widget.metaType = 'widget';
|
|
434
|
+
}
|
|
433
435
|
if (this.docId === window.apos.adminBar.contextId) {
|
|
434
436
|
apos.bus.$emit('context-edited', {
|
|
435
437
|
[`@${widget._id}`]: widget
|
|
@@ -513,6 +515,9 @@ export default {
|
|
|
513
515
|
if (!widget._id) {
|
|
514
516
|
widget._id = cuid();
|
|
515
517
|
}
|
|
518
|
+
if (!widget.metaType) {
|
|
519
|
+
widget.metaType = 'widget';
|
|
520
|
+
}
|
|
516
521
|
const push = {
|
|
517
522
|
$each: [ widget ]
|
|
518
523
|
};
|
|
@@ -96,12 +96,6 @@ module.exports = {
|
|
|
96
96
|
self.connectionReused = true;
|
|
97
97
|
return;
|
|
98
98
|
}
|
|
99
|
-
let Logger;
|
|
100
|
-
if (process.env.APOS_MONGODB_LOG_LEVEL) {
|
|
101
|
-
Logger = require('mongodb').Logger;
|
|
102
|
-
// Set debug level
|
|
103
|
-
Logger.setLevel(process.env.APOS_MONGODB_LOG_LEVEL);
|
|
104
|
-
}
|
|
105
99
|
let uri = 'mongodb://';
|
|
106
100
|
if (process.env.APOS_MONGODB_URI) {
|
|
107
101
|
uri = process.env.APOS_MONGODB_URI;
|
|
@@ -37,8 +37,7 @@ module.exports = {
|
|
|
37
37
|
self.apos.isNew = await self.detectNew();
|
|
38
38
|
await self.createIndexes();
|
|
39
39
|
self.addLegacyMigrations();
|
|
40
|
-
self.
|
|
41
|
-
self.addSetPreviousDocsAposModeMigration();
|
|
40
|
+
self.addMigrations();
|
|
42
41
|
},
|
|
43
42
|
restApiRoutes(self) {
|
|
44
43
|
return {
|
|
@@ -120,10 +119,23 @@ module.exports = {
|
|
|
120
119
|
'@apostrophecms/doc-type:beforeInsert': {
|
|
121
120
|
setLocaleAndMode(req, doc, options) {
|
|
122
121
|
const manager = self.getManager(doc.type);
|
|
123
|
-
if (manager.isLocalized()) {
|
|
124
|
-
|
|
125
|
-
|
|
122
|
+
if (!manager.isLocalized()) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (doc._id) {
|
|
127
|
+
const [ _id, locale, mode ] = doc._id.split(':');
|
|
128
|
+
doc.aposLocale = `${locale}:${mode}`;
|
|
129
|
+
doc.aposMode = mode;
|
|
130
|
+
return;
|
|
126
131
|
}
|
|
132
|
+
|
|
133
|
+
const [ locale, mode ] = doc.aposLocale
|
|
134
|
+
? doc.aposLocale.split(':')
|
|
135
|
+
: [ req.locale, req.mode ];
|
|
136
|
+
|
|
137
|
+
doc.aposLocale = `${locale}:${mode}`;
|
|
138
|
+
doc.aposMode = mode;
|
|
127
139
|
},
|
|
128
140
|
testPermissionsAndAddIdAndCreatedAt(req, doc, options) {
|
|
129
141
|
self.testInsertPermissions(req, doc, options);
|
|
@@ -1751,38 +1763,14 @@ module.exports = {
|
|
|
1751
1763
|
}
|
|
1752
1764
|
}
|
|
1753
1765
|
},
|
|
1754
|
-
// Add the "cacheInvalidatedAt" field to the documents that do not have it yet,
|
|
1755
|
-
// and set it to equal doc.updatedAt.
|
|
1756
|
-
setCacheField() {
|
|
1757
|
-
return self.apos.migration.eachDoc({ cacheInvalidatedAt: { $exists: 0 } }, 5, async doc => {
|
|
1758
|
-
await self.apos.doc.db.updateOne({ _id: doc._id }, {
|
|
1759
|
-
$set: { cacheInvalidatedAt: doc.updatedAt }
|
|
1760
|
-
});
|
|
1761
|
-
});
|
|
1762
|
-
},
|
|
1763
|
-
addCacheFieldMigration() {
|
|
1764
|
-
self.apos.migration.add('add-cache-invalidated-at-field', self.setCacheField);
|
|
1765
|
-
},
|
|
1766
|
-
|
|
1767
|
-
async addSetPreviousDocsAposModeMigration () {
|
|
1768
|
-
self.apos.migration.add('set-previous-docs-apos-mode', async () => {
|
|
1769
|
-
await self.apos.doc.db.updateMany({
|
|
1770
|
-
_id: { $regex: ':previous$' },
|
|
1771
|
-
aposMode: { $ne: 'previous' }
|
|
1772
|
-
}, {
|
|
1773
|
-
$set: {
|
|
1774
|
-
aposMode: 'previous'
|
|
1775
|
-
}
|
|
1776
|
-
});
|
|
1777
|
-
});
|
|
1778
|
-
},
|
|
1779
1766
|
|
|
1780
1767
|
async bestAposDocId(criteria) {
|
|
1781
1768
|
const existing = await self.apos.doc.db.findOne(criteria, { projection: { aposDocId: 1 } });
|
|
1782
1769
|
return existing?.aposDocId || self.apos.util.generateId();
|
|
1783
1770
|
},
|
|
1784
1771
|
|
|
1785
|
-
...require('./lib/legacy-migrations')(self)
|
|
1772
|
+
...require('./lib/legacy-migrations')(self),
|
|
1773
|
+
...require('./lib/migrations')(self)
|
|
1786
1774
|
};
|
|
1787
1775
|
}
|
|
1788
1776
|
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
module.exports = (self) => {
|
|
2
|
+
return {
|
|
3
|
+
addMigrations() {
|
|
4
|
+
self.addCacheFieldMigration();
|
|
5
|
+
self.addSetPreviousDocsAposModeMigration();
|
|
6
|
+
self.addSetDocumentModesMigration();
|
|
7
|
+
},
|
|
8
|
+
|
|
9
|
+
addCacheFieldMigration() {
|
|
10
|
+
self.apos.migration.add('add-cache-invalidated-at-field', self.setCacheField);
|
|
11
|
+
},
|
|
12
|
+
|
|
13
|
+
async addSetPreviousDocsAposModeMigration () {
|
|
14
|
+
self.apos.migration.add('set-previous-docs-apos-mode', async () => {
|
|
15
|
+
await self.apos.doc.db.updateMany({
|
|
16
|
+
_id: { $regex: ':previous$' },
|
|
17
|
+
aposMode: { $ne: 'previous' }
|
|
18
|
+
}, {
|
|
19
|
+
$set: {
|
|
20
|
+
aposMode: 'previous'
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
addSetDocumentModesMigration() {
|
|
27
|
+
self.apos.migration.add('set-document-modes', async () => {
|
|
28
|
+
return self.apos.migration.eachDoc({}, 5, async (doc) => {
|
|
29
|
+
const manager = self.getManager(doc.type);
|
|
30
|
+
if (!manager.isLocalized()) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const idMode = doc._id.split(':').pop(); ;
|
|
34
|
+
const [ locale, localeMode ] = doc.aposLocale.split(':');
|
|
35
|
+
const aposMode = doc.aposMode;
|
|
36
|
+
|
|
37
|
+
if (idMode !== localeMode || idMode !== aposMode) {
|
|
38
|
+
await self.apos.doc.db.updateOne({ _id: doc._id }, {
|
|
39
|
+
$set: {
|
|
40
|
+
aposLocale: `${locale}:${idMode}`,
|
|
41
|
+
aposMode: idMode
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
// Add the "cacheInvalidatedAt" field to the documents that do not have it yet,
|
|
50
|
+
// and set it to equal doc.updatedAt.
|
|
51
|
+
setCacheField() {
|
|
52
|
+
return self.apos.migration.eachDoc({ cacheInvalidatedAt: { $exists: 0 } }, 5, async doc => {
|
|
53
|
+
await self.apos.doc.db.updateOne({ _id: doc._id }, {
|
|
54
|
+
$set: { cacheInvalidatedAt: doc.updatedAt }
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
};
|
|
@@ -2703,8 +2703,11 @@ module.exports = {
|
|
|
2703
2703
|
subquery.limit(undefined);
|
|
2704
2704
|
subquery.page(undefined);
|
|
2705
2705
|
subquery.perPage(undefined);
|
|
2706
|
-
|
|
2707
|
-
const count = await
|
|
2706
|
+
await subquery.finalize();
|
|
2707
|
+
const count = await self.apos.doc.db.countDocuments({
|
|
2708
|
+
...subquery.get('criteria'),
|
|
2709
|
+
...(subquery.get('lateCriteria') || {})
|
|
2710
|
+
});
|
|
2708
2711
|
if (query.get('perPage')) {
|
|
2709
2712
|
const perPage = query.get('perPage');
|
|
2710
2713
|
const totalPages = Math.ceil(count / perPage);
|
|
@@ -554,12 +554,13 @@ module.exports = {
|
|
|
554
554
|
}
|
|
555
555
|
if (!sessionOptions.store.name) {
|
|
556
556
|
// require from this module's dependencies
|
|
557
|
-
|
|
557
|
+
const MongoStore = require('connect-mongo');
|
|
558
|
+
sessionOptions.store = MongoStore.create(sessionOptions.store.options);
|
|
558
559
|
} else {
|
|
559
560
|
// require from project's dependencies
|
|
560
561
|
Store = self.apos.root.require(sessionOptions.store.name)(expressSession);
|
|
562
|
+
sessionOptions.store = new Store(sessionOptions.store.options);
|
|
561
563
|
}
|
|
562
|
-
sessionOptions.store = new Store(sessionOptions.store.options);
|
|
563
564
|
}
|
|
564
565
|
// Exported for the benefit of code that needs to
|
|
565
566
|
// interoperate in a compatible way with express-sessions
|
|
@@ -339,13 +339,17 @@
|
|
|
339
339
|
"richTextHorizontalRule": "Horizontale Linie",
|
|
340
340
|
"richTextItalic": "Kursiv",
|
|
341
341
|
"richTextLink": "Link",
|
|
342
|
+
"richTextMarkApplyStyles": "Stil anwenden",
|
|
343
|
+
"richTextMarkMultipleStyles": "Mehrere stile...",
|
|
344
|
+
"richTextMarkStyles": "Inline Stile",
|
|
345
|
+
"richTextNodeStyles": "Block Stile",
|
|
346
|
+
"richTextNodeMultipleStyles": "Mehrere blocks...",
|
|
342
347
|
"richTextOrderedList": "Nummerierte Liste",
|
|
343
348
|
"richTextParagraph": "Paragraph",
|
|
344
349
|
"richTextPlaceholder": "Beginne dein Text hier...",
|
|
345
350
|
"richTextRedo": "Wiederholen",
|
|
346
351
|
"richTextStrikethrough": "Durchgestrichen",
|
|
347
352
|
"richTextStyleConfigWarning": "Falsche Konfiguration des Text-Stiles: {{ label }}, {{ tag }}",
|
|
348
|
-
"richTextStyles": "Stile",
|
|
349
353
|
"richTextUnderline": "Unterstrichen",
|
|
350
354
|
"richTextUndo": "Rückgängig",
|
|
351
355
|
"safeModeActive": "Sicherer Modus aktiv, HTML-Code wird nicht gerendert.",
|
|
@@ -398,6 +398,11 @@
|
|
|
398
398
|
"richTextInsertMenuHeading": "Insert element...",
|
|
399
399
|
"richTextItalic": "Italic",
|
|
400
400
|
"richTextLink": "Link",
|
|
401
|
+
"richTextMarkApplyStyles": "Apply Styles",
|
|
402
|
+
"richTextMarkMultipleStyles": "Multiple Styles...",
|
|
403
|
+
"richTextMarkStyles": "Inline Styles",
|
|
404
|
+
"richTextNodeStyles": "Block Styles",
|
|
405
|
+
"richTextNodeMultipleStyles": "Multiple Blocks...",
|
|
401
406
|
"richTextOrderedList": "Ordered List",
|
|
402
407
|
"richTextParagraph": "Paragraph (P)",
|
|
403
408
|
"richTextPlaceholder": "Start Typing Here...",
|
|
@@ -405,7 +410,6 @@
|
|
|
405
410
|
"richTextRedo": "Redo",
|
|
406
411
|
"richTextStrikethrough": "Strike",
|
|
407
412
|
"richTextStyleConfigWarning": "Misconfigured rich text style: label: {{ label }}, {{ tag }}",
|
|
408
|
-
"richTextStyles": "Styles",
|
|
409
413
|
"richTextUnderline": "Underline",
|
|
410
414
|
"richTextUndo": "Undo",
|
|
411
415
|
"safeModeActive": "Running in safe mode, not showing raw HTML.",
|
|
@@ -324,13 +324,17 @@
|
|
|
324
324
|
"richTextHorizontalRule": "Regla Horizontal",
|
|
325
325
|
"richTextItalic": "Cursiva",
|
|
326
326
|
"richTextLink": "Liga",
|
|
327
|
+
"richTextMarkApplyStyles": "Aplicar estilo",
|
|
328
|
+
"richTextMarkMultipleStyles": "Estilo múltiple...",
|
|
329
|
+
"richTextMarkStyles": "Estilos en línea",
|
|
330
|
+
"richTextNodeStyles": "Estilos en bloque",
|
|
331
|
+
"richTextNodeMultipleStyles": "Bloque múltiple...",
|
|
327
332
|
"richTextOrderedList": "Lista Ordenada",
|
|
328
333
|
"richTextParagraph": "Párrafo (P)",
|
|
329
334
|
"richTextPlaceholder": "Comience a escribir aquí...",
|
|
330
335
|
"richTextRedo": "Rehacer",
|
|
331
336
|
"richTextStrikethrough": "Tachar",
|
|
332
337
|
"richTextStyleConfigWarning": "Estilo de texto enriquecido mal configurado: etiqueta: {{ label }}, {{ tag }}",
|
|
333
|
-
"richTextStyles": "Estilos",
|
|
334
338
|
"richTextUnderline": "Subrayar",
|
|
335
339
|
"richTextUndo": "Deshacer",
|
|
336
340
|
"safeModeActive": "Trabajando en modo seguro, HTML sin procesar no aparece.",
|
|
@@ -332,13 +332,17 @@
|
|
|
332
332
|
"richTextHorizontalRule": "Règle Horizontale",
|
|
333
333
|
"richTextItalic": "Italique",
|
|
334
334
|
"richTextLink": "Lien",
|
|
335
|
+
"richTextMarkApplyStyles": "Appliquer le style",
|
|
336
|
+
"richTextMarkMultipleStyles": "Plusieurs styles...",
|
|
337
|
+
"richTextMarkStyles": "Styles de ligne",
|
|
338
|
+
"richTextNodeStyles": "Styles de bloc",
|
|
339
|
+
"richTextNodeMultipleStyles": "Plusieurs blocs...",
|
|
335
340
|
"richTextOrderedList": "Liste numérotée",
|
|
336
341
|
"richTextParagraph": "Paragraphe (P)",
|
|
337
342
|
"richTextPlaceholder": "Commencez à écrire ici...",
|
|
338
343
|
"richTextRedo": "Refaire",
|
|
339
344
|
"richTextStrikethrough": "Barrer",
|
|
340
345
|
"richTextStyleConfigWarning": "Style du Texte Riche mal configuré : label : {{ label }}, {{ tag }}",
|
|
341
|
-
"richTextStyles": "Styles",
|
|
342
346
|
"richTextUnderline": "Souligner",
|
|
343
347
|
"richTextUndo": "Annuler",
|
|
344
348
|
"safeModeActive": "Fonctionne en mode sans échec, n'affiche pas le code HTML brut.",
|
|
@@ -384,6 +384,11 @@
|
|
|
384
384
|
"richTextInsertMenuHeading": "Inserisci elemento...",
|
|
385
385
|
"richTextItalic": "Corsivo",
|
|
386
386
|
"richTextLink": "Link",
|
|
387
|
+
"richTextMarkApplyStyles": "Applicare lo stile",
|
|
388
|
+
"richTextMarkMultipleStyles": "Stile multiplo...",
|
|
389
|
+
"richTextMarkStyles": "Stili in linea",
|
|
390
|
+
"richTextNodeStyles": "Stili di blocco",
|
|
391
|
+
"richTextNodeMultipleStyles": "Blocco multiplo...",
|
|
387
392
|
"richTextOrderedList": "Lista ordinata",
|
|
388
393
|
"richTextParagraph": "Paragrafo (P)",
|
|
389
394
|
"richTextPlaceholder": "Inizia a scrivere qui...",
|
|
@@ -391,7 +396,6 @@
|
|
|
391
396
|
"richTextRedo": "Ricomincia",
|
|
392
397
|
"richTextStrikethrough": "Barrato",
|
|
393
398
|
"richTextStyleConfigWarning": "Stile del rich-text configurato in modo errato: etichetta: {{ label }}, {{ tag }}",
|
|
394
|
-
"richTextStyles": "Stili",
|
|
395
399
|
"richTextUnderline": "Sottolinea",
|
|
396
400
|
"richTextUndo": "Annulla",
|
|
397
401
|
"safeModeActive": "Esecuzione in modalità sicura, non visualizzando l'HTML grezzo.",
|
|
@@ -321,13 +321,17 @@
|
|
|
321
321
|
"richTextHorizontalRule": "Regra Horizontal",
|
|
322
322
|
"richTextItalic": "Itálico",
|
|
323
323
|
"richTextLink": "Link",
|
|
324
|
+
"richTextMarkApplyStyles": "Aplicar estilo",
|
|
325
|
+
"richTextMarkMultipleStyles": "Estilo múltiplo...",
|
|
326
|
+
"richTextMarkStyles": "Estilos incorporado",
|
|
327
|
+
"richTextNodeStyles": "Estilos de bloco",
|
|
328
|
+
"richTextNodeMultipleStyles": "Bloco múltiplo...",
|
|
324
329
|
"richTextOrderedList": "Lista Ordenada",
|
|
325
330
|
"richTextParagraph": "Parágrafo (P)",
|
|
326
331
|
"richTextPlaceholder": "Comece a digitar aqui...",
|
|
327
332
|
"richTextRedo": "Refazer",
|
|
328
333
|
"richTextStrikethrough": "Tachar",
|
|
329
334
|
"richTextStyleConfigWarning": "Estilo do editor desconfigurado: etiqueta: {{ label }}, {{ tag }}",
|
|
330
|
-
"richTextStyles": "Estilos",
|
|
331
335
|
"richTextUnderline": "Sublinhar",
|
|
332
336
|
"richTextUndo": "Desfazer",
|
|
333
337
|
"safeModeActive": "Executando em modo de segurança, não mostrando HTML puro.",
|
|
@@ -336,13 +336,17 @@
|
|
|
336
336
|
"richTextHorizontalRule": "Horizontálne pravítko",
|
|
337
337
|
"richTextItalic": "Kurzíva",
|
|
338
338
|
"richTextLink": "Link",
|
|
339
|
+
"richTextMarkApplyStyles": "Aplikovať štýl",
|
|
340
|
+
"richTextMarkMultipleStyles": "Viacnásobný štýl...",
|
|
341
|
+
"richTextMarkStyles": "Inline štýly",
|
|
342
|
+
"richTextNodeStyles": "Blokový štýly",
|
|
343
|
+
"richTextNodeMultipleStyles": "Viacnásobný Blokový...",
|
|
339
344
|
"richTextOrderedList": "Číslovaný zoznam",
|
|
340
345
|
"richTextParagraph": "Odstavec (P)",
|
|
341
346
|
"richTextPlaceholder": "Začnite písať tu...",
|
|
342
347
|
"richTextRedo": "Prerobiť",
|
|
343
348
|
"richTextStrikethrough": "Preškrtnúť ",
|
|
344
349
|
"richTextStyleConfigWarning": "Nesprávne nakonfigurovaný štýl: popiska: {{ label }}, {{ tag }}",
|
|
345
|
-
"richTextStyles": "Štýly",
|
|
346
350
|
"richTextUnderline": "Podčiarknúť",
|
|
347
351
|
"richTextUndo": "Vrátiť späť",
|
|
348
352
|
"safeModeActive": "Beží v núdzovom režime, nezobrazuje sa zdrojový HTML.",
|
|
@@ -309,7 +309,7 @@ module.exports = {
|
|
|
309
309
|
// Remove locale prefix so URL parsing can proceed normally from here
|
|
310
310
|
if (req.path === localeOptions.prefix) {
|
|
311
311
|
// Add / for home page
|
|
312
|
-
|
|
312
|
+
req.redirect = `${req.url}/`;
|
|
313
313
|
}
|
|
314
314
|
if (req.path.substring(0, localeOptions.prefix.length + 1) === localeOptions.prefix + '/') {
|
|
315
315
|
req.path = req.path.replace(localeOptions.prefix, '');
|
|
@@ -115,6 +115,11 @@ module.exports = {
|
|
|
115
115
|
// https://groups.google.com/forum/#!topic/mongodb-user/AFC1ia7MHzk
|
|
116
116
|
const cursor = collection.find(criteria);
|
|
117
117
|
cursor.sort({ _id: 1 });
|
|
118
|
+
// TODO use a variant of the code below instead
|
|
119
|
+
// cursor.batchSize(limit);
|
|
120
|
+
// for await (const docs of cursor) {
|
|
121
|
+
// // await iterator(docs);
|
|
122
|
+
// }
|
|
118
123
|
return require('util').promisify(broadband)(cursor, limit, async function (doc, cb) {
|
|
119
124
|
try {
|
|
120
125
|
await iterator(doc);
|
|
@@ -58,8 +58,8 @@ function onTopOf(el1, el2) {
|
|
|
58
58
|
if (el2 === document) {
|
|
59
59
|
return true;
|
|
60
60
|
}
|
|
61
|
-
const index1 = apos.modal.stack.findIndex(modal => modal
|
|
62
|
-
const index2 = apos.modal.stack.findIndex(modal => modal
|
|
61
|
+
const index1 = apos.modal.stack.findIndex(modal => modal.modalEl === el1);
|
|
62
|
+
const index2 = apos.modal.stack.findIndex(modal => modal.modalEl === el2);
|
|
63
63
|
if (index1 === -1) {
|
|
64
64
|
throw new Error('apos.modal.onTopOf: el1 is not in the modal stack');
|
|
65
65
|
}
|