comand-component-library 3.3.77 → 3.3.78

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,74 +1,32 @@
1
1
  <template>
2
2
  <!-- begin edit-mode -->
3
- <figure v-if="editModeContext?.editing" :class="['cmd-image flex-container vertical', getTextAlign]">
4
- <CmdFormElement
5
- element="input"
6
- type="checkbox"
7
- :toggleSwitch="true"
8
- labelText="Show figcaption"
9
- v-model="editableShowFigcaption"
10
- />
11
- <CmdFormElement
12
- element="select"
13
- labelText="Figcaption Position"
14
- :selectOptions="positionOptions"
15
- :disabled="!showFigcaption"
16
- v-model="editableFigcaptionPosition"
17
- />
18
- <CmdFormElement
19
- element="select"
20
- labelText="Figcaption text alignment"
21
- :selectOptions="textAlignOptions"
22
- :disabled="!showFigcaption"
23
- v-model="editableFigcaptionTextAlign"
24
- />
25
- <CmdFormElement element="input" type="text" :required="true" labelText="Alternative Text"
26
- v-model="editableAlternativeText"/>
27
- <CmdFormElement element="input" type="text" :required="false" labelText="Tooltip" v-model="editableTooltip"/>
28
-
3
+ <figure v-if="editing" :class="['cmd-image flex-container vertical', getTextAlign]">
29
4
  <template v-if="figcaption?.position === 'top'">
30
- <CmdFormElement element="input" type="text" :required="true" labelText="Text figcaption"
31
- v-model="editableFigcaptionText"/>
5
+ <CmdFormElement
6
+ element="input"
7
+ type="text"
8
+ :required="true"
9
+ labelText="Text figcaption"
10
+ v-model="editableFigcaptionText"
11
+ />
32
12
  </template>
33
13
  <div :class="['box drop-area flex-container vertical', { 'allow-drop': allowDrop }]" v-on="dragAndDropHandler" title="Drag new image to this area to replace old one!">
34
14
  <span class="icon-image"></span>
35
- <img ref="contentImage" :src="image.src" :alt="image.alt" :title="image.tooltip"/>
15
+ <img :src="imageSource" :alt="image.alt" :title="image.tooltip"/>
36
16
  </div>
37
- <button
38
- type="button"
39
- :class="['button upload primary', { disabled: uploadInitiated }]"
40
- :disabled="uploadInitiated"
41
- @click="selectFiles()"
42
- >
43
- <!-- begin CmdIcon -->
44
- <CmdIcon iconClass="icon-loop"/>
45
- <!-- end CmdIcon -->
46
- <span>Select image</span>
47
- </button>
17
+
48
18
  <template v-if="figcaption?.position !== 'top'">
49
19
  <CmdFormElement
50
- element="input"
51
- type="text"
52
- :class="getTextAlign"
53
- :required="true"
54
- labelText="Text figcaption"
55
- v-model="editableFigcaptionText"
20
+ element="input"
21
+ type="text"
22
+ :class="getTextAlign"
23
+ :required="true"
24
+ labelText="Text figcaption"
25
+ :showLabel="false"
26
+ v-model="editableFigcaptionText"
56
27
  />
57
28
  </template>
58
29
  </figure>
59
-
60
- <!-- begin CmdFormElement -->
61
- <CmdFormElement
62
- v-if="editModeContext?.editing"
63
- class="hidden"
64
- element="input"
65
- type="file"
66
- labelText="Select file"
67
- :disabled="uploadInitiated"
68
- @change="fileSelected"
69
- ref="formElement"
70
- />
71
- <!-- end CmdFormElement -->
72
30
  <!-- end edit-mode -->
73
31
 
74
32
  <figure v-else :class="['cmd-image', getTextAlign]">
@@ -79,21 +37,19 @@
79
37
  </template>
80
38
 
81
39
  <script>
82
- import {getFileExtension} from "../utils/getFileExtension"
40
+ import {checkAndUploadFile} from "../utils/checkAndUploadFile"
41
+ import EditMode from "../mixins/EditMode.vue"
42
+ import {updateHandlerProvider} from "../utils/editmode.js"
83
43
 
84
44
  export default {
85
45
  name: "CmdImage",
86
- inject: {
87
- editModeContext: {
88
- default: null
89
- }
90
- },
46
+ mixins: [EditMode],
91
47
  data() {
92
48
  return {
93
49
  mediumMaxWidth: 1023,
94
50
  smallMaxWidth: 600,
95
51
  currentWindowWidth: window.innerWidth,
96
- allowedFileExtensions: ["jpg", "jpeg", "png"],
52
+ allowedFileExtensions: ["jpg", "jpeg", "png", "webp"],
97
53
  uploadInitiated: false,
98
54
  allowDrop: false,
99
55
  showFigcaption: true,
@@ -101,6 +57,7 @@ export default {
101
57
  figcaptionTextAlign: null,
102
58
  tooltip: null,
103
59
  alternativeText: null,
60
+ newImageSource: null,
104
61
  positionOptions: [
105
62
  {
106
63
  text: "Above image",
@@ -128,13 +85,7 @@ export default {
128
85
  figcaptionText: null
129
86
  }
130
87
  },
131
- mounted() {
132
- this.editModeContext?.addSaveHandler(this.onSave)
133
- },
134
88
  props: {
135
- editModeContextData: {
136
- type: Object
137
- },
138
89
  /**
139
90
  * image-object including source, alternative text, tooltip (not required)
140
91
  */
@@ -158,7 +109,7 @@ export default {
158
109
  },
159
110
  minImageWidth: {
160
111
  type: Number,
161
- default: 1025
112
+ default: 600
162
113
  }
163
114
  },
164
115
  created() {
@@ -175,6 +126,11 @@ export default {
175
126
  },
176
127
  computed: {
177
128
  imageSource() {
129
+ // check if a new image is provided
130
+ if(this.newImageSource) {
131
+ return this.newImageSource
132
+ }
133
+
178
134
  // if only one src exists
179
135
  const imgSrc = this.image.src
180
136
 
@@ -194,6 +150,12 @@ export default {
194
150
  // else return large (will be used if images for small-and -medium-devices do not exist or if screen resolution is larger than mediumMaxWidth)
195
151
  return imgSrc.large
196
152
  },
153
+ getTextAlign() {
154
+ if (this.figcaption?.textAlign) {
155
+ return "text-" + this.figcaption.textAlign
156
+ }
157
+ return ''
158
+ },
197
159
  dragAndDropHandler() {
198
160
  // register handlers only if drag-and-drop is enabled
199
161
  return {
@@ -203,55 +165,9 @@ export default {
203
165
  drop: this.drop
204
166
  }
205
167
  },
206
- getTextAlign() {
207
- if (this.figcaption?.textAlign) {
208
- return "text-" + this.figcaption.textAlign
209
- }
210
- return ''
211
- },
212
- editableAlternativeText: {
213
- get() {
214
- return this.alternativeText == null ? this.image.alt : this.alternativeText
215
- },
216
- set(value) {
217
- this.alternativeText = value
218
- }
219
- },
220
- editableTooltip: {
221
- get() {
222
- return this.tooltip == null ? this.image.tooltip : this.tooltip
223
- },
224
- set(value) {
225
- this.tooltip = value
226
- }
227
- },
228
- editableShowFigcaption: {
229
- get() {
230
- return this.showFigcaption == null ? this.figcaption.show : this.showFigcaption
231
- },
232
- set(value) {
233
- this.showFigcaption = value
234
- }
235
- },
236
- editableFigcaptionPosition: {
237
- get() {
238
- return this.figcaptionPosition == null ? this.figcaption.position : this.figcaptionPosition
239
- },
240
- set(value) {
241
- this.figcaptionPosition = value
242
- }
243
- },
244
- editableFigcaptionTextAlign: {
245
- get() {
246
- return this.figcaptionTextAlign || this.figcaption.textAlign
247
- },
248
- set(value) {
249
- this.figcaptionTextAlign = value
250
- }
251
- },
252
168
  editableFigcaptionText: {
253
169
  get() {
254
- return this.figcaptionText || this.figcaption.text
170
+ return this.figcaptionText == null ? this.figcaption.text : this.figcaptionText
255
171
  },
256
172
  set(value) {
257
173
  this.figcaptionText = value
@@ -273,15 +189,6 @@ export default {
273
189
  }
274
190
  }
275
191
  },
276
- fileSelected(event) {
277
- if (event.target.files.length > 0) {
278
- this.checkAndUploadFile(event.target.files[0])
279
- }
280
- },
281
- selectFiles() {
282
- let inputFile = this.$refs.formElement.getDomElement().querySelector("input[type='file']")
283
- inputFile.click()
284
- },
285
192
  dragEnter(event) {
286
193
  this.dragOver(event)
287
194
  },
@@ -306,80 +213,40 @@ export default {
306
213
  this.allowDrop = false
307
214
  if (event.dataTransfer && event.dataTransfer.files && event.dataTransfer.files.length > 0) {
308
215
  event.preventDefault()
309
- this.checkAndUploadFile(event.dataTransfer.files[0])
216
+ checkAndUploadFile(event.dataTransfer.files[0], this.allowedFileExtensions, this.minImageWidth, this.maxFileUploadSize, (imageSource) => this.newImageSource = imageSource)
310
217
  }
311
218
  },
312
- onSave() {
313
- const data = {
314
- image: {
315
- alt: this.editableAlternativeText,
316
- tooltip: this.editableTooltip
219
+ addHandlerProvider() {
220
+ const itemStructure = {
221
+ "image": {
222
+ "id": createUuid(),
223
+ "src": "media/images/demo-images/large/landscape-06.jpg",
224
+ "srcImageLarge": "media/images/demo-images/large/landscape-06.jpg",
225
+ "alt": "Alternative Text"
317
226
  },
318
- figcaption: {
319
- position: this.editableFigcaptionPosition,
320
- textAlign: this.editableFigcaptionTextAlign,
321
- text: this.editableFigcaptionText,
322
- show: this.editableShowFigcaption
227
+ "figcaption": {
228
+ "show": true,
229
+ "position": "bottom",
230
+ "text": "Figcaption",
231
+ "textAlign": "center"
323
232
  }
324
233
  }
325
- return {
326
- editModeContextData: this.editModeContextData,
327
- ...data,
234
+ return updateHandlerProvider(this, {
235
+ item() {
236
+ return itemStructure
237
+ }
238
+ })
239
+ },
240
+ updateHandlerProvider() {
241
+ const figcaptionText = this.editableFigcaptionText
242
+ return updateHandlerProvider(this, {
328
243
  update(props) {
329
- console.log("CmdImage.update", props)
330
- if (!props.image) {
331
- props.image = {}
332
- }
333
- props.image.alt = data.image.alt
334
- props.image.tooltip = data.image.tooltip
335
244
  if (!props.figcaption) {
336
245
  props.figcaption = {}
337
246
  }
338
- props.figcaption.position = data.figcaption.position
339
- props.figcaption.textAlign = data.figcaption.textAlign
340
- props.figcaption.text = data.figcaption.text
341
- props.figcaption.show = data.figcaption.show
247
+ props.figcaption.text = figcaptionText
342
248
  }
343
- }
344
- },
345
- checkAndUploadFile(file) {
346
- const errorMessages = []
347
-
348
- // check size for current file
349
- if (file.size > this.maxFileUploadSize) {
350
- errorMessages.push("file too large")
351
- }
352
-
353
- // check if current file has allowed file-type
354
- if (!this.allowedFileExtensions.includes(getFileExtension(file.name))) {
355
- errorMessages.push("disallowed file extension")
356
- }
357
-
358
- if (errorMessages.length) {
359
- alert(errorMessages)
360
- return
361
- }
362
-
363
- // check for min dimensions
364
- const image = new Image()
365
-
366
- image.onload = () => {
367
- if (image.width < this.minImageWidth) {
368
- // errorMessages.push("width (" + image.width + " px) too small - at least " + this.minImageWidth + " px required!")
369
- const confirmUpload = confirm("width (" + image.width + " px) too small - at least " + this.minImageWidth + " px required! Use trotzdem!")
370
- if (!confirmUpload) {
371
- alert("Abbruch")
372
- return
373
- }
374
- }
375
- // revoke URL to clean memory
376
- URL.revokeObjectURL(image.src)
377
-
378
- // show preview-image by assigning image.src (containing image date (not its path) to do existing contentImage source
379
- this.$refs.contentImage.src = image.src
380
- }
381
- // create data-url (contains content of a file (not its path))
382
- image.src = URL.createObjectURL(file)
249
+ })
383
250
  }
384
251
  }
385
252
  }
@@ -388,6 +255,10 @@ export default {
388
255
  <style lang="scss">
389
256
  /* begin cmd-image ------------------------------------------------------------------------------------------ */
390
257
  .cmd-image {
258
+ img {
259
+ display: block;
260
+ }
261
+
391
262
  &.text-center {
392
263
  figcaption {
393
264
  text-align: center;
@@ -430,4 +301,4 @@ export default {
430
301
  }
431
302
 
432
303
  /* end cmd-image ------------------------------------------------------------------------------------------ */
433
- </style>
304
+ </style>
@@ -0,0 +1,29 @@
1
+ <script>
2
+ import {findEditComponentWrapper} from "../utils/editmode.js"
3
+
4
+ export default {
5
+ inject: {
6
+ editModeContext: {
7
+ default: null
8
+ }
9
+ },
10
+ data() {
11
+ return {
12
+ editing: false
13
+ }
14
+ },
15
+ created() {
16
+ const editComponentWrapper = findEditComponentWrapper(this.$parent)
17
+ if (editComponentWrapper) {
18
+ editComponentWrapper.addEditStateListener(editing => this.editing = editing)
19
+ editComponentWrapper.addUpdateHandlerProvider(this.updateHandlerProvider)
20
+ editComponentWrapper.setAddHandlerProvider(this.addHandlerProvider)
21
+ }
22
+ },
23
+ methods: {
24
+ updateHandlerProvider() {
25
+ return {}
26
+ }
27
+ }
28
+ }
29
+ </script>
@@ -0,0 +1,48 @@
1
+ import {getFileExtension} from "./getFileExtension.js"
2
+
3
+ function checkAndUploadFile(file, allowedFileExtensions, minImageWidth, maxFileUploadSize, imagePreview) {
4
+ const errorMessages = []
5
+
6
+ // check size for current file
7
+ if (file.size > maxFileUploadSize) {
8
+ errorMessages.push("file too large")
9
+ }
10
+
11
+ // check if current file has allowed file-type
12
+ if (!allowedFileExtensions.includes(getFileExtension(file.name))) {
13
+ errorMessages.push("disallowed file extension")
14
+ }
15
+
16
+ if (errorMessages.length) {
17
+ alert(errorMessages)
18
+ return
19
+ }
20
+
21
+ // check for min dimensions
22
+ const image = new Image()
23
+
24
+ image.onload = () => {
25
+ if (image.width < minImageWidth) {
26
+ // errorMessages.push("width (" + image.width + " px) too small - at least " + this.minImageWidth + " px required!")
27
+ const confirmUpload = confirm("width (" + image.width + " px) too small - at least " + minImageWidth + " px required! Use trotzdem!")
28
+ if (!confirmUpload) {
29
+ alert("Cancel")
30
+ return
31
+ }
32
+ }
33
+ // revoke URL to clean memory
34
+ URL.revokeObjectURL(image.src)
35
+
36
+ // show preview-image by assigning image.src (containing image date (not its path) to do existing contentImage source
37
+ if(typeof imagePreview === "function") {
38
+ imagePreview(image.src)
39
+ } else {
40
+ imagePreview.src = image.src
41
+ }
42
+
43
+ }
44
+ // create data-url (contains content of a file (not its path))
45
+ image.src = URL.createObjectURL(file)
46
+ }
47
+
48
+ export { checkAndUploadFile }
@@ -0,0 +1,42 @@
1
+ function findEditComponentWrapper(component) {
2
+ if (component?.$options?.name === "EditComponentWrapper") {
3
+ return component
4
+ }
5
+ if (component?.$parent) {
6
+ return findEditComponentWrapper(component.$parent)
7
+ }
8
+ return null
9
+ }
10
+
11
+ function buildComponentPath(component, ...extraPathElements) {
12
+ const path = []
13
+ for (let parent = findEditComponentWrapper(component); parent; parent = findEditComponentWrapper(parent.$parent)) {
14
+ path.unshift(...parent.componentPath)
15
+ }
16
+ path.push(...extraPathElements)
17
+ return path
18
+ }
19
+
20
+ function componentPathAsString(componentPath) {
21
+ if (Array.isArray(componentPath) && componentPath.length > 0) {
22
+ return JSON.stringify(componentPath)
23
+ }
24
+ return ""
25
+ }
26
+
27
+ function updateHandlerProvider(component, options) {
28
+ if (component?.$options?.name) {
29
+ return {
30
+ name: component.$options.name,
31
+ ...options
32
+ }
33
+ }
34
+ return options
35
+ }
36
+
37
+ export {
38
+ findEditComponentWrapper,
39
+ buildComponentPath,
40
+ componentPathAsString,
41
+ updateHandlerProvider
42
+ }