apostrophe 4.4.3 → 4.5.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.
Files changed (89) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/index.js +2 -3
  3. package/lib/glob.js +12 -0
  4. package/lib/moog-require.js +3 -3
  5. package/modules/@apostrophecms/admin-bar/index.js +9 -2
  6. package/modules/@apostrophecms/admin-bar/ui/apos/apps/AposAdminBar.js +1 -1
  7. package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposAdminBar.vue +1 -0
  8. package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposAdminBarMenu.vue +1 -0
  9. package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposContextBar.vue +2 -2
  10. package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposContextTitle.vue +0 -1
  11. package/modules/@apostrophecms/area/ui/apos/components/AposAreaContextualMenu.vue +2 -2
  12. package/modules/@apostrophecms/area/ui/apos/components/AposAreaEditor.vue +6 -6
  13. package/modules/@apostrophecms/area/ui/apos/components/AposAreaExpandedMenu.vue +7 -1
  14. package/modules/@apostrophecms/asset/index.js +5 -6
  15. package/modules/@apostrophecms/command-menu/index.js +7 -2
  16. package/modules/@apostrophecms/doc/index.js +2 -2
  17. package/modules/@apostrophecms/doc-type/index.js +1 -1
  18. package/modules/@apostrophecms/i18n/i18n/en.json +37 -1
  19. package/modules/@apostrophecms/i18n/index.js +2 -2
  20. package/modules/@apostrophecms/i18n/ui/apos/components/AposI18nLocalize.vue +5 -5
  21. package/modules/@apostrophecms/image/index.js +1 -1
  22. package/modules/@apostrophecms/image/ui/apos/components/AposImageRelationshipEditor.vue +4 -3
  23. package/modules/@apostrophecms/image/ui/apos/components/AposMediaManager.vue +221 -76
  24. package/modules/@apostrophecms/image/ui/apos/components/AposMediaManagerDisplay.vue +91 -24
  25. package/modules/@apostrophecms/image/ui/apos/components/AposMediaManagerEditor.vue +49 -51
  26. package/modules/@apostrophecms/image/ui/apos/components/AposMediaManagerSelections.vue +1 -0
  27. package/modules/@apostrophecms/login/index.js +3 -3
  28. package/modules/@apostrophecms/modal/ui/apos/components/AposDocsManagerToolbar.vue +3 -11
  29. package/modules/@apostrophecms/modal/ui/apos/components/AposModal.vue +5 -12
  30. package/modules/@apostrophecms/modal/ui/apos/components/AposModalBody.vue +20 -6
  31. package/modules/@apostrophecms/modal/ui/apos/components/AposModalBreadcrumbs.vue +1 -1
  32. package/modules/@apostrophecms/modal/ui/apos/components/AposModalShareDraft.vue +1 -1
  33. package/modules/@apostrophecms/modal/ui/apos/components/AposModalTabs.vue +3 -5
  34. package/modules/@apostrophecms/modal/ui/apos/components/AposModalToolbar.vue +1 -0
  35. package/modules/@apostrophecms/modal/ui/apos/components/AposWidgetModalTabs.vue +3 -5
  36. package/modules/@apostrophecms/modal/ui/apos/mixins/AposDocErrorsMixin.js +2 -2
  37. package/modules/@apostrophecms/modal/ui/apos/mixins/AposDocsManagerMixin.js +44 -39
  38. package/modules/@apostrophecms/modal/ui/apos/mixins/AposModalTabsMixin.js +2 -2
  39. package/modules/@apostrophecms/oembed/index.js +2 -2
  40. package/modules/@apostrophecms/oembed-field/ui/apos/components/AposInputOembed.vue +2 -2
  41. package/modules/@apostrophecms/page/ui/apos/components/AposPagesManager.vue +1 -2
  42. package/modules/@apostrophecms/page/ui/apos/logic/AposPagesManager.js +14 -7
  43. package/modules/@apostrophecms/piece-type/ui/apos/components/AposDocsManager.vue +23 -11
  44. package/modules/@apostrophecms/piece-type/ui/apos/components/AposDocsManagerDisplay.vue +4 -1
  45. package/modules/@apostrophecms/rich-text-widget/index.js +31 -3
  46. package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposRichTextWidgetEditor.vue +1 -1
  47. package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposTiptapColor.vue +285 -0
  48. package/modules/@apostrophecms/rich-text-widget/ui/apos/tiptap-extensions/Color.js +5 -0
  49. package/modules/@apostrophecms/schema/lib/addFieldTypes.js +26 -13
  50. package/modules/@apostrophecms/schema/ui/apos/components/AposInputBoolean.vue +2 -2
  51. package/modules/@apostrophecms/schema/ui/apos/components/AposInputColor.vue +0 -1
  52. package/modules/@apostrophecms/schema/ui/apos/components/AposInputObject.vue +1 -0
  53. package/modules/@apostrophecms/schema/ui/apos/components/AposInputWrapper.vue +13 -2
  54. package/modules/@apostrophecms/schema/ui/apos/components/AposSchema.vue +4 -0
  55. package/modules/@apostrophecms/schema/ui/apos/logic/AposArrayEditor.js +11 -9
  56. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputArea.js +4 -4
  57. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputArray.js +7 -7
  58. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputObject.js +11 -0
  59. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputSlug.js +45 -51
  60. package/modules/@apostrophecms/schema/ui/apos/logic/AposSchema.js +3 -1
  61. package/modules/@apostrophecms/schema/ui/apos/mixins/AposInputMixin.js +1 -1
  62. package/modules/@apostrophecms/submitted-draft/index.js +2 -2
  63. package/modules/@apostrophecms/ui/ui/apos/components/AposButton.vue +7 -3
  64. package/modules/@apostrophecms/ui/ui/apos/components/AposButtonSplit.vue +0 -1
  65. package/modules/@apostrophecms/ui/ui/apos/components/AposContextMenu.vue +13 -4
  66. package/modules/@apostrophecms/ui/ui/apos/components/AposFile.vue +4 -4
  67. package/modules/@apostrophecms/ui/ui/apos/components/AposFilterMenu.vue +2 -1
  68. package/modules/@apostrophecms/ui/ui/apos/components/AposLoading.vue +1 -1
  69. package/modules/@apostrophecms/ui/ui/apos/components/AposLoadingBlock.vue +50 -0
  70. package/modules/@apostrophecms/ui/ui/apos/components/AposSlat.vue +0 -1
  71. package/modules/@apostrophecms/ui/ui/apos/components/AposSlatList.vue +6 -4
  72. package/modules/@apostrophecms/ui/ui/apos/components/AposTagApply.vue +17 -11
  73. package/modules/@apostrophecms/ui/ui/apos/components/AposTree.vue +2 -2
  74. package/modules/@apostrophecms/ui/ui/apos/components/AposTreeRows.vue +2 -2
  75. package/modules/@apostrophecms/ui/ui/apos/lib/tooltip.js +2 -2
  76. package/modules/@apostrophecms/ui/ui/apos/scss/global/_normalize.scss +0 -1
  77. package/modules/@apostrophecms/ui/ui/apos/scss/global/_tables.scss +1 -0
  78. package/modules/@apostrophecms/ui/ui/apos/stores/modal.js +3 -3
  79. package/modules/@apostrophecms/user/index.js +1 -0
  80. package/modules/@apostrophecms/util/index.js +12 -4
  81. package/modules/@apostrophecms/widget-type/ui/apos/components/AposWidgetEditor.vue +2 -2
  82. package/package.json +8 -7
  83. package/scripts/lint-i18n.js +8 -3
  84. package/test/command-menu.js +76 -12
  85. package/test/pages-rest.js +2 -2
  86. package/test/pieces.js +11 -11
  87. package/test/recursionGuard.js +5 -5
  88. package/test/utils/commands.js +26 -0
  89. package/test-lib/util.js +2 -2
@@ -96,6 +96,7 @@ export default {
96
96
  if (newValue.length) {
97
97
  this.generateUi();
98
98
  }
99
+
99
100
  if (this.selectPending.size > 0) {
100
101
  const newChecked = [ ...this.checked, ...this.selectPending ];
101
102
  this.checked = [ ...new Set(newChecked) ];
@@ -111,58 +112,31 @@ export default {
111
112
  doc._fields = this.subfields[doc._id];
112
113
  }
113
114
  }
115
+ },
116
+ checked() {
117
+ this.updateCheckedDocs();
114
118
  }
115
119
  },
116
120
  methods: {
117
- addCheckedDoc(docOrId) {
118
- this.concatCheckedDocs([ docOrId ]);
119
- },
120
- setCheckedDocs(docsOrIds) {
121
- const docs = this.getDocs(docsOrIds);
122
-
123
- this.checked = docs.map(item => item._id);
124
- this.checkedDocs = docs;
125
- },
126
- concatCheckedDocs(docsOrIds) {
127
- const docs = this.getDocs(docsOrIds);
128
-
129
- this.checked = [ ...this.checked, ...docs.map(({ _id }) => _id) ];
130
- this.checkedDocs = [ ...this.checkedDocs, ...docs ];
131
- },
132
- removeCheckedDoc(id) {
133
- this.checked = this.checked.filter((checkedId) => checkedId !== id);
134
- this.checkedDocs = this.checkedDocs.filter((doc) => doc.id !== id);
135
- },
136
- getDocs(docsOrIds) {
137
- const items = this.moduleOptions.name === '@apostrophecms/page'
138
- ? this.pagesFlat
139
- : this.items;
140
-
141
- return docsOrIds.map(docOrId => {
142
- return docOrId._id
143
- ? docOrId
144
- : items.find(item => item._id === docOrId);
145
- });
146
- },
147
121
  // It would have been nice for this to be computed, however
148
122
  // AposMediaManagerDisplay does not re-render when it is
149
123
  // a computed prop rather than a method call in the template.
150
- maxReached() {
124
+ maxReached(checkedCount = this.checked.length) {
151
125
  // Reaching max and exceeding it are different things
152
- return this.relationshipField.max &&
153
- this.checked.length >= this.relationshipField.max;
126
+ return this.relationshipField.max && checkedCount >= this.relationshipField.max;
154
127
  },
155
128
  selectAll() {
156
129
  if (!this.checked.length) {
130
+ const ids = [];
157
131
  this.items.forEach((item) => {
158
132
  const notPublished = this.manuallyPublished && !item.lastPublishedAt;
159
- if (this.relationshipField && (this.maxReached() || notPublished)) {
133
+ if (this.relationshipField && (this.maxReached(ids.length) || notPublished)) {
160
134
  return;
161
135
  }
162
-
163
- this.addCheckedDoc(item);
136
+ ids.push(item._id);
164
137
  });
165
138
 
139
+ this.checked = ids;
166
140
  return;
167
141
  }
168
142
 
@@ -170,7 +144,7 @@ export default {
170
144
  this.allPiecesSelection.isSelected = false;
171
145
  }
172
146
 
173
- this.setCheckedDocs([]);
147
+ this.checked = [];
174
148
  },
175
149
  iconSize(header) {
176
150
  if (header.icon) {
@@ -231,7 +205,13 @@ export default {
231
205
  return true;
232
206
  }
233
207
  if (this.relationshipField.schema) {
234
- if (detectDocChange(this.relationshipField.schema, this.chosen[i]._fields, this.checkedDocs[i]._fields)) {
208
+ if (
209
+ detectDocChange(
210
+ this.relationshipField.schema,
211
+ this.chosen[i]._fields,
212
+ this.checkedDocs[i]._fields
213
+ )
214
+ ) {
235
215
  return true;
236
216
  }
237
217
  }
@@ -243,7 +223,9 @@ export default {
243
223
  docsManagerRemoveEventHandlers() {
244
224
  apos.bus.$off('content-changed', this.docsManagerOnContentChanged);
245
225
  },
246
- docsManagerOnContentChanged({ doc, select }) {
226
+ docsManagerOnContentChanged({
227
+ doc, select, action
228
+ }) {
247
229
  if (!select) {
248
230
  return;
249
231
  }
@@ -258,6 +240,29 @@ export default {
258
240
  // a published doc _id without a fuss
259
241
  this.selectPending.add(doc._id.replace(':published', ':draft'));
260
242
  }
243
+ },
244
+ // update this.checkedDocs based on this.checked. The default
245
+ // implementation is suitable for paginated lists. Can be overridden
246
+ // for other cases.
247
+ updateCheckedDocs() {
248
+ // Keep `checkedDocs` in sync with `checked`, first removing from
249
+ // `checkedDocs` if no longer in `checked`
250
+ this.checkedDocs = this.checkedDocs.filter(doc => {
251
+ return this.checked.includes(doc._id);
252
+ });
253
+ // then adding to `checkedDocs` if not there yet. These should be in
254
+ // `items` which is assumed to contain a flat list of items currently
255
+ // visible.
256
+ //
257
+ // TODO: Once we have the option to select all docs of a type even if not
258
+ // currently visible in the manager this will need to make calls to the
259
+ // database.
260
+ this.checked.forEach(id => {
261
+ if (this.checkedDocs.findIndex(doc => doc._id === id) === -1) {
262
+ const found = this.items.find(item => item._id === id);
263
+ found && this.checkedDocs.push(found);
264
+ }
265
+ });
261
266
  }
262
267
  }
263
268
  };
@@ -1,4 +1,4 @@
1
- import cuid from 'cuid';
1
+ import { createId } from '@paralleldrive/cuid2';
2
2
 
3
3
  // Provide basic bridging functionality between tabs
4
4
  // and the modal body.
@@ -6,7 +6,7 @@ import cuid from 'cuid';
6
6
  export default {
7
7
  data() {
8
8
  return {
9
- tabKey: cuid(),
9
+ tabKey: createId(),
10
10
  currentTab: null
11
11
  };
12
12
  },
@@ -97,7 +97,7 @@ module.exports = {
97
97
  // Tolerant URL handling
98
98
  url = self.apos.launder.url(url, null, true);
99
99
  if (!url) {
100
- throw self.apos.error('invalid', 'Video URL invalid');
100
+ throw self.apos.error('invalid', req.t('apostrophe:oembedVideoUrlInvalid'));
101
101
  }
102
102
  const key = url + ':' + JSON.stringify(options);
103
103
  let response = await self.apos.cache.get('@apostrophecms/oembed', key);
@@ -110,7 +110,7 @@ module.exports = {
110
110
  try {
111
111
  response = await require('util').promisify(self.oembetter.fetch)(url, options);
112
112
  } catch (err) {
113
- throw self.apos.error('invalid', 'Video URL invalid');
113
+ throw self.apos.error('invalid', req.t('apostrophe:oembedVideoUrlInvalid'));
114
114
  }
115
115
  }
116
116
  // Make non-secure URLs protocol relative and
@@ -94,7 +94,7 @@ export default {
94
94
  this.field.oembedType && this.oembedResult.type &&
95
95
  this.oembedResult.type !== this.field.oembedType
96
96
  ) {
97
- return { message: 'Embed type not supported' };
97
+ return { message: this.$t('apostrophe:oembedTypeNotSupported') };
98
98
  } else if (this.oembedError) {
99
99
  return this.oembedError.message ? {
100
100
  message: this.oembedError.message
@@ -137,7 +137,7 @@ export default {
137
137
  if (error.body && error.body.message) {
138
138
  this.oembedError = error.body;
139
139
  } else {
140
- this.oembedError = { message: 'Invalid embed URL' };
140
+ this.oembedError = { message: this.$t('apostrophe:oembedInvalidEmbedUrl') };
141
141
  }
142
142
  this.next.title = '';
143
143
  this.next.thumbnail = '';
@@ -79,13 +79,12 @@
79
79
  </template>
80
80
  <template #bodyMain>
81
81
  <AposTree
82
- :checked="checked"
82
+ v-model:checked="checked"
83
83
  :items="items"
84
84
  :headers="headers"
85
85
  :icons="icons"
86
86
  :options="treeOptions"
87
87
  :module-options="moduleOptions"
88
- @update:checked="setCheckedDocs"
89
88
  @update="update"
90
89
  />
91
90
  </template>
@@ -54,16 +54,16 @@ export default {
54
54
  },
55
55
  moreMenu: [
56
56
  {
57
- label: 'New Page',
57
+ label: 'apostrophe:newPage',
58
58
  action: 'new'
59
59
  }
60
60
  ],
61
61
  moreMenuButton: {
62
62
  tooltip: {
63
- content: 'More Options',
63
+ content: 'apostrophe:moreOptions',
64
64
  placement: 'bottom'
65
65
  },
66
- label: 'More Options',
66
+ label: 'apostrophe:moreOptions',
67
67
  icon: 'dots-vertical-icon',
68
68
  iconOnly: true,
69
69
  type: 'subtle',
@@ -95,9 +95,9 @@ export default {
95
95
  },
96
96
  saveRelationshipLabel() {
97
97
  if (this.relationshipField && (this.relationshipField.max === 1)) {
98
- return 'Select Page';
98
+ return 'apostrophe:selectPage';
99
99
  } else {
100
- return 'Select Pages';
100
+ return 'apostrophe:selectPages';
101
101
  }
102
102
  },
103
103
  headers() {
@@ -253,11 +253,12 @@ export default {
253
253
  },
254
254
  toggleRowCheck(id) {
255
255
  if (this.checked.includes(id)) {
256
- this.removeCheckedDoc(id);
256
+ this.checked = this.checked.filter(item => item !== id);
257
257
  } else {
258
- this.addCheckedDoc(id);
258
+ this.checked = [ ...this.checked, id ];
259
259
  }
260
260
  },
261
+ // This is not used for now
261
262
  selectAll(event) {
262
263
  if (!this.checked.length) {
263
264
  this.pagesFlat.forEach((row) => {
@@ -288,6 +289,12 @@ export default {
288
289
  this.checkedDocs.push(doc);
289
290
  this.checked.push(doc._id);
290
291
  }
292
+ },
293
+ setCheckedDocs(checkedDocs) {
294
+ this.checked = checkedDocs.map(doc => doc._id);
295
+ },
296
+ updateCheckedDocs() {
297
+ this.checkedDocs = this.checked.map(_id => this.pagesFlat.find(page => page._id === _id));
291
298
  }
292
299
  }
293
300
  };
@@ -102,7 +102,7 @@
102
102
  <template #bodyMain>
103
103
  <AposDocsManagerDisplay
104
104
  v-if="items.length > 0"
105
- :checked="checked"
105
+ v-model:checked="checked"
106
106
  :items="items"
107
107
  :headers="headers"
108
108
  :options="{
@@ -111,7 +111,6 @@
111
111
  disableUnpublished: disableUnpublished,
112
112
  manuallyPublished: manuallyPublished
113
113
  }"
114
- @update:checked="setCheckedDocs"
115
114
  @open="edit"
116
115
  />
117
116
  <div v-else class="apos-pieces-manager__empty">
@@ -244,13 +243,13 @@ export default {
244
243
  await this.getAllPiecesTotal();
245
244
  this.modal.triggerFocusRefresh++;
246
245
 
247
- apos.bus.$on('content-changed', this.getPieces);
246
+ apos.bus.$on('content-changed', this.onContentChanged);
248
247
  apos.bus.$on('command-menu-manager-create-new', this.create);
249
248
  apos.bus.$on('command-menu-manager-close', this.confirmAndCancel);
250
249
  },
251
250
  unmounted() {
252
251
  this.destroyShortcuts();
253
- apos.bus.$off('content-changed', this.getPieces);
252
+ apos.bus.$off('content-changed', this.onContentChanged);
254
253
  apos.bus.$off('command-menu-manager-create-new', this.create);
255
254
  apos.bus.$off('command-menu-manager-close', this.confirmAndCancel);
256
255
  },
@@ -427,15 +426,17 @@ export default {
427
426
  const result = await apos.modal.execute('AposRelationshipEditor', {
428
427
  schema: this.relationshipField.schema,
429
428
  title: item.title,
430
- value: item._fields
429
+ modelValue: item._fields
431
430
  });
432
431
  if (result) {
433
- const index = this.checkedDocs.findIndex(_item => _item._id === item._id);
434
- // TODO verify it's still reactive, should be based on the doc
435
- // Or use a filter here
436
- this.checkedDocs.splice(index, 1, {
437
- ...this.checkedDocs[index],
438
- _fields: result
432
+ this.checkedDocs = this.checkedDocs.map((doc) => {
433
+ if (doc._id !== item._id) {
434
+ return doc;
435
+ }
436
+ return {
437
+ ...doc,
438
+ _fields: result
439
+ };
439
440
  });
440
441
  }
441
442
  },
@@ -476,6 +477,17 @@ export default {
476
477
  console.error(error);
477
478
  }
478
479
  }
480
+ },
481
+ setCheckedDocs(checked) {
482
+ this.checkedDocs = checked;
483
+ this.checked = this.checkedDocs.map(item => {
484
+ return item._id;
485
+ });
486
+ },
487
+
488
+ async onContentChanged({ doc, action }) {
489
+ await this.getPieces();
490
+ this.getAllPiecesTotal();
479
491
  }
480
492
  }
481
493
  };
@@ -52,7 +52,10 @@
52
52
  :field="{
53
53
  name: item._id,
54
54
  hideLabel: true,
55
- label: `Toggle selection of ${item.title}`,
55
+ label: $t({
56
+ key: 'apostrophe:toggleSelectionOf',
57
+ title: item.title
58
+ }),
56
59
  readOnly:
57
60
  (options.disableUnchecked && !checkProxy.includes(item._id)) ||
58
61
  (options.disableUnpublished && !item.lastPublishedAt)
@@ -290,6 +290,11 @@ module.exports = {
290
290
  component: 'AposTiptapImage',
291
291
  label: 'apostrophe:image',
292
292
  icon: 'image-icon'
293
+ },
294
+ color: {
295
+ component: 'AposTiptapColor',
296
+ label: 'apostrophe:richTextColor',
297
+ command: 'setColor'
293
298
  }
294
299
  },
295
300
  editorInsertMenu: {
@@ -477,7 +482,8 @@ module.exports = {
477
482
  subscript: [ 'sub' ],
478
483
  table: [ 'table', 'tr', 'td', 'th' ],
479
484
  image: [ 'figure', 'img', 'figcaption' ],
480
- div: [ 'div' ]
485
+ div: [ 'div' ],
486
+ color: [ 'span' ]
481
487
  };
482
488
  for (const item of self.combinedItems(options)) {
483
489
  if (simple[item]) {
@@ -547,7 +553,11 @@ module.exports = {
547
553
  tag: 'img',
548
554
  attributes: [ 'src', 'alt' ]
549
555
  }
550
- ]
556
+ ],
557
+ color: {
558
+ tag: '*',
559
+ attributes: [ 'style' ]
560
+ }
551
561
  };
552
562
  for (const item of self.combinedItems(options)) {
553
563
  if (simple[item]) {
@@ -590,6 +600,23 @@ module.exports = {
590
600
  properties: {
591
601
  'text-align': [ /^justify$/ ]
592
602
  }
603
+ },
604
+ color: {
605
+ selector: '*',
606
+ properties: {
607
+ color: [
608
+ // Hexadecimal colors (3 or 6 digits, optionally with alpha)
609
+ /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8}|[0-9a-fA-F]{4})$/i,
610
+ // RGB colors
611
+ /^rgb\(\s*(?:\d{1,3}\s*,\s*){2}\d{1,3}\s*\)$/,
612
+ // RGBA colors
613
+ /^rgba\(\s*(?:\d{1,3}\s*,\s*){3}(?:0?\.\d+|1(?:\.0)?)\s*\)$/,
614
+ // HSL colors
615
+ /^hsl\(\s*\d{1,3}(?:deg)?\s*,\s*\d{1,3}%\s*,\s*\d{1,3}%\s*\)$/,
616
+ // HSLA colors
617
+ /^hsla\(\s*\d{1,3}(?:deg)?\s*,\s*\d{1,3}%\s*,\s*\d{1,3}%\s*,\s*(?:0?\.\d+|1(?:\.0)?)\s*\)$/
618
+ ]
619
+ }
593
620
  }
594
621
  };
595
622
  for (const item of self.combinedItems(options)) {
@@ -891,7 +918,8 @@ module.exports = {
891
918
  placeholderTextWithInsertMenu: self.options.placeholderTextWithInsertMenu,
892
919
  linkWithType: Array.isArray(self.options.linkWithType) ? self.options.linkWithType : [ self.options.linkWithType ],
893
920
  linkSchema: self.linkSchema,
894
- imageStyles: self.options.imageStyles
921
+ imageStyles: self.options.imageStyles,
922
+ color: self.options.color
895
923
  };
896
924
  return finalData;
897
925
  }
@@ -13,7 +13,7 @@
13
13
  animation: 'fade',
14
14
  inertia: true,
15
15
  placement: 'bottom',
16
- hideOnClick: true
16
+ hideOnClick: false
17
17
  }"
18
18
  :editor="editor"
19
19
  >